I am trying to do product version control in Python scripts for a specific reason, but I couldn't figure out how to do it in an elegant way.
Currently, I am doing something like the below. However, the scripts are hard to maintain when version content is changed.
class Product(object): def __init__(client): self.version = client.version # Get client version from another module def function(): if self.version == '1.0': print('for version 1.0') elif self.version == '2.0': print('for version 2.0') else: print(f'function not support {self.version}')
Therefore, I want to do something like the below to separate the functions with the same name.
class Product(object): def __init__(client): self.version = client.version # Get client version from another module def function(): print('for version 1.0') def function(): print('for version 2.0')
I was thinking about to use decorator to achieve this:
class Product(object): def __init__(client): self.version = client.version # Get client version from another module @version(1.0) def function(): print('for version 1.0') @version(2.0) def function(): print('for version 2.0')
However, I failed to figure out how... it seems like a decorator cannot do this kind operation or I just don't understand how to.
Is there a elegant way to do this?
There are two ways to call another method function from the same class. First, you can use a dot/period to access the method from the class variable. Second, you can simply call the function and pass the class object as an argument.
There are two methods to call a function from string stored in a variable. The first one is by using the window object method and the second one is by using eval() method. The eval() method is older and it is deprecated.
Use locals() and globals() to Call a Function From a String in Python. Another way to call a function from a string is by using the built-in functions locals() and globals . These two functions return a Python dictionary that represents the current symbol table of the given source code.
You need to use the import keyword along with the desired module name. When interpreter comes across an import statement, it imports the module to your current program. You can use the functions inside a module by using a dot(.) operator along with the module name.
Could you put your Product
class into two modules, v1 and v2, then import them conditionally?
For example:
Productv1.py
class Product(object): def function(): print('for version 1.0')
Productv2.py
class Product(object): def function(): print('for version 2.0')
Then in your main file:
main.py
if client.version == '1.0': from Productv1 import Product elif client.version == '2.0': from Productv2 import Product else: print(f'function not support {self.version}') p = Product p.function()
Inheritance is probably the best way to do this, but since you asked specifically about decorators, I wanted to show you could do this using decorators.
You'll need to use a dictionary to store your functions by version, and then look up which version to use at runtime. Here's an example.
version_store = {} def version(v): def dec(f): name = f.__qualname__ version_store[(name, v)] = f def method(self, *args, **kwargs): f = version_store[(name, self.version)] return f(self, *args, **kwargs) return method return dec class Product(object): def __init__(self, version): self.version = version @version("1.0") def function(self): print("1.0") @version("2.0") def function(self): print("2.0") Product("1.0").function() Product("2.0").function()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With