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?
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()