Following my last post, I'm gonna write a bit more on Python. This time I'm gonna show how we can add to the part where we were replacing methods with vars and vars with methods at runtime. The thing is, this can also be expanded to replace methods with other methods at runtime. This means that we can actually swap out a method's implementation at runtime if we need to do so. First of let's create a simple class called Planet
1 2 3 4 5 6 7 8 9 | class Planet(): def __init__(self, planetName): self.name = planetName def writeInfo(self): print("Planet Name: " + self.name) earth = Planet("Earth") #Create a new planet instance with the name Earth earth.writeInfo() #Will print out "Planet Name: Earth" |
This example should be straightforward we create a class definition with an init method (constructor) and a method to write out the info we know about the planet instance. And a small example with Earth. Now let's say this system is running 24/7, and we suddenly need to have the mass of planets included, and we need to write the information as well. What do we do? Well we can try to replace the methods for the class at runtime! So let's expand the example a bit
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | class Planet(): def __init__(self, planetName): self.name = planetName def writeInfo(self): print("Planet Name: " + self.name + "\n") earth = Planet("Earth") #Create a new planet instance with the name Earth earth.writeInfo() #Write the new implementation of the init method (constructor) for the Planet class def newInit(self, planetName, planetMass): self.name = planetName self.mass = planetMass #Write the new implementation of the writeInfo method for the Planet class def newWriteInfo(self): print("Planet name: " + self.name) #If the planet mass is defined write it, or else tell that we haven't defined it yet for that planet try: print(" Planet mass: " + self.mass) except AttributeError as e: print(" Planet mass unknown") print("") #Print automatically creates a new line. #Replace the methods at class level. Planet.__init__ = newInit Planet.writeInfo = newWriteInfo mars = Planet("Mars", "639E21kg") mars.writeInfo() #Prints out "Planet name: Mars\n Planet mass: 639E21kg" earth.writeInfo() #Prints out "Planet name: Earth\n Planet mass unknown" |
What happens in the new example is: first we have the class like before, no changes at all. Afterwards we define two new methods that we will use to replace the original class methods for planet. So from now on each time a Planet instance is created, we have to provide both a name and a mass for the planet. We also changed the implementation of the write info. We already know that all planets have a name defined, so we can just print the planet name. However, as we have introduced the mass later on, we cannot be sure that the mass variable exists for every instance, so we wrap the print in a try, except block. We first try to write out the planet mass and if we get an AttributeError (because the variable is not defined) we move to the except block and writes out that the mass is unknown.
The complete output will look like this:
1 2 3 4 5 6 7 | Planet Name: Earth Planet name: Earth Planet mass unknown Planet name: Mars Planet mass: 639E21kg |
This is an interesting feature of Python and is quite fun to play around with, however, i think you have to be careful if you are to use this in a production setup. As you can easily introduce errors when you replace methods like this, so at least test it before just throwing in a new implementation. Once again the code examples can be executed using python 3 (Yes I don't like python 2 as much, as I think there are some weird syntax here and there. Such as the print and the except syntax).
- Archi