Same name functions in same class, elegant way to determine which to call?
Clash Royale CLAN TAG#URR8PPP
up vote
21
down vote
favorite
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 - please help.
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... seems like a decorator cannot do this kind operation or I just don't understand how to.
Is there any elegant way to do this?
python version-control python-3.6 python-decorators
add a comment |Â
up vote
21
down vote
favorite
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 - please help.
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... seems like a decorator cannot do this kind operation or I just don't understand how to.
Is there any elegant way to do this?
python version-control python-3.6 python-decorators
1
The "standard" way to solve this would be to haveProductV1
andProductV2
then yourProduct
class simply has an_impl
attribute that is assigned to aProductV<version>
and all the methods are forwarded likedef function(self): return self._impl.function()
. In python you could even avoid defining them by using__getattr__
. Also:ProductVX
would simply define the basic operations and you can put inProduct
the facade methods that you can build on top of the basic methods.
– Bakuriu
2 days ago
I forgot to say: by "standard solution" I mean: this is what you'd do in most programming languages where you cannot use stuff like decorators for example. Also: if you have big classes using decorators makes your class quite big and hard to work with. It's easier to separate completely the version-specific implementations.
– Bakuriu
2 days ago
add a comment |Â
up vote
21
down vote
favorite
up vote
21
down vote
favorite
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 - please help.
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... seems like a decorator cannot do this kind operation or I just don't understand how to.
Is there any elegant way to do this?
python version-control python-3.6 python-decorators
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 - please help.
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... seems like a decorator cannot do this kind operation or I just don't understand how to.
Is there any elegant way to do this?
python version-control python-3.6 python-decorators
python version-control python-3.6 python-decorators
edited 2 days ago


BartoszKP
26.1k106299
26.1k106299
asked 2 days ago


Timmy Lin
1087
1087
1
The "standard" way to solve this would be to haveProductV1
andProductV2
then yourProduct
class simply has an_impl
attribute that is assigned to aProductV<version>
and all the methods are forwarded likedef function(self): return self._impl.function()
. In python you could even avoid defining them by using__getattr__
. Also:ProductVX
would simply define the basic operations and you can put inProduct
the facade methods that you can build on top of the basic methods.
– Bakuriu
2 days ago
I forgot to say: by "standard solution" I mean: this is what you'd do in most programming languages where you cannot use stuff like decorators for example. Also: if you have big classes using decorators makes your class quite big and hard to work with. It's easier to separate completely the version-specific implementations.
– Bakuriu
2 days ago
add a comment |Â
1
The "standard" way to solve this would be to haveProductV1
andProductV2
then yourProduct
class simply has an_impl
attribute that is assigned to aProductV<version>
and all the methods are forwarded likedef function(self): return self._impl.function()
. In python you could even avoid defining them by using__getattr__
. Also:ProductVX
would simply define the basic operations and you can put inProduct
the facade methods that you can build on top of the basic methods.
– Bakuriu
2 days ago
I forgot to say: by "standard solution" I mean: this is what you'd do in most programming languages where you cannot use stuff like decorators for example. Also: if you have big classes using decorators makes your class quite big and hard to work with. It's easier to separate completely the version-specific implementations.
– Bakuriu
2 days ago
1
1
The "standard" way to solve this would be to have
ProductV1
and ProductV2
then your Product
class simply has an _impl
attribute that is assigned to a ProductV<version>
and all the methods are forwarded like def function(self): return self._impl.function()
. In python you could even avoid defining them by using __getattr__
. Also: ProductVX
would simply define the basic operations and you can put in Product
the facade methods that you can build on top of the basic methods.– Bakuriu
2 days ago
The "standard" way to solve this would be to have
ProductV1
and ProductV2
then your Product
class simply has an _impl
attribute that is assigned to a ProductV<version>
and all the methods are forwarded like def function(self): return self._impl.function()
. In python you could even avoid defining them by using __getattr__
. Also: ProductVX
would simply define the basic operations and you can put in Product
the facade methods that you can build on top of the basic methods.– Bakuriu
2 days ago
I forgot to say: by "standard solution" I mean: this is what you'd do in most programming languages where you cannot use stuff like decorators for example. Also: if you have big classes using decorators makes your class quite big and hard to work with. It's easier to separate completely the version-specific implementations.
– Bakuriu
2 days ago
I forgot to say: by "standard solution" I mean: this is what you'd do in most programming languages where you cannot use stuff like decorators for example. Also: if you have big classes using decorators makes your class quite big and hard to work with. It's easier to separate completely the version-specific implementations.
– Bakuriu
2 days ago
add a comment |Â
7 Answers
7
active
oldest
votes
up vote
23
down vote
accepted
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 the your functions by version, 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()
3
You probably wantf.__qualname__
to avoid conflict betweenProduct.function
andAmbassadorial.function
...
– Amadan
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separateversion_store
per class?
– Bergi
2 days ago
2
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
 |Â
show 1 more comment
up vote
7
down vote
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()
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
2
@TimmyLin In that case, you could have a base class, sayProduct
that holds all the duplicated content, then have aProductv1
andProductv2
that inherits it and just holds what is different. That way there's no duplicated code.
– Loocid
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
add a comment |Â
up vote
5
down vote
As another option, you could go for some factory to create your class.
Create your versioned functions (note the self
parameter). This can be done in a different module. Also, add some collection to fetch the function based on the version number.
def func_10(self):
print('for version 1.0')
def func_20(self):
print('for version 2.0')
funcs = "1.0": func_10,
"2.0": func_20
Add a base class that contains the static parts of your implementation and a utility class to create your instances in:
class Product:
def __init__(self, version):
self.version = version
class ProductFactory(type):
@classmethod
def get_product_class(mcs, version):
# this will return an instance right away, due to the (version) in the end
return type.__new__(mcs, "Product_".format(version.replace(".","")), (Product,), "function": funcs.get(version))(version)
# if you want to return a class object to instantiate in your code omit the (version) in the end
Using this:
p1 = ProductFactory.get_product_class("1.0")
p2 = ProductFactory.get_product_class("2.0")
print(p1.__class__.__name__) # Product_10
p1.function() # for version 1.0
print(p1.function) # <bound method func_10 of <__main__.Product_10 object at 0x0000000002A157F0>>
print(p2.__class__.__name__) # Product_20
p2.function() # for version 2.0
print(p2.function) # <bound method func_20 of <__main__.Product_20 object at 0x0000000002A15860>>
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variablesp1, p2
, but this is absolutely a good answer. Thank you!
– Timmy Lin
2 days ago
1
@TimmyLin Actually, the functions are not separated into two variables.p1
andp2
are separate instances of subclasses ofProduct
, each with their own implementation offunction
based on theversion
(which is supposed to be yourclient.version
). Basically, this example builds the class with the implementation offunction
that is required for the given version instead of having one class implementing all possible 'versions' offunction
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)
– shmee
2 days ago
1
BTW: you could replaceProductFactor
with aProduct
class and define a__new__
method to do what theget_product_class
does. In this way the code has less boiler-plate.
– Bakuriu
2 days ago
add a comment |Â
up vote
4
down vote
In general, don't. Method overloading is discouraged in Python. If you have to differentiate on class level, read @Loocid's answer. I won't repeat his excellent post.
If you want in on a method level because the difference is small enough for that, try something like this:
class Product:
def method(self):
if self.version == "1.0":
return self._methodv1()
elif self.version == "2.0":
return self._methodv2()
else:
raise ValueError("No appropriate method for version ".format(self.version))
def _methodv1(self):
# implementation
def _methodv2(self):
# implementation
Note here:
- Use of methods starting with an underscore, to indicate those are
the implementation. - Keeping the methods nice and tidy without
contamination between the versions - Raising an error for unexpected versions (crash early and hard).
- In my not so humble opinion, this will be a lot clearer for other people reading your post than using decorators.
Or:
class Product:
def method_old(self):
# transform arguments to v2 method:
return self.method()
def method(self):
# implementation
- In case you want to totally deprecate previous useage, and want to drop version 1.0 support in the future.
- Be sure to give deprecation warnings, so to not surprise users of a library with sudden changes.
- Arguably the better solution if nobody else uses your code.
I get the vibe my first method would be more suitable to your problem at hand, but I wanted to include the second for posterity. If you edit your code 10 years from now, that one will make you happier. If you edit code using the current code tomorrow, the first method will make you happier.
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
add a comment |Â
up vote
0
down vote
You can use decorators for this
def v_decorate(func):
def func_wrapper(name):
return func(name)
return func_wrapper
And
@v_decorate
def get_version(name):
return "for version 0 ".format(name)
You can call it
get_version(1.0)
'for version 1.0 '
get_version(2.0)
'for version 2.0 '
I am sorry, I am not sure if I understand this correctly. Thev_decorate
is to add an extra argumentname
to the original function? don't understand how to combine this to my same name functions.. Orz
– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version tov_decorate
and put into called function is kinda extra steps. Modify my function tofunction(self): print(f'for version self.version')
can do the exactly same thing without decorator..
– Timmy Lin
2 days ago
4
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
add a comment |Â
up vote
0
down vote
I'm not a python developer but I can't help but wonder why you don't just do something like this:
class Product(object):
def __init__(self, version):
self.version = version
def function(self):
print('for version ' + self.version)
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
add a comment |Â
up vote
0
down vote
Or you can do, dict.get
to call a function and do print
in lambda
if nothing is right:
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Example:
class Product(object):
def __init__(self,version):
self.version = version
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Product('1.0').function()
Product('2.0').function()
Product('3.0').function()
Output:
for version 1.0
for version 2.0
function not support 3.0
add a comment |Â
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
23
down vote
accepted
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 the your functions by version, 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()
3
You probably wantf.__qualname__
to avoid conflict betweenProduct.function
andAmbassadorial.function
...
– Amadan
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separateversion_store
per class?
– Bergi
2 days ago
2
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
 |Â
show 1 more comment
up vote
23
down vote
accepted
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 the your functions by version, 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()
3
You probably wantf.__qualname__
to avoid conflict betweenProduct.function
andAmbassadorial.function
...
– Amadan
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separateversion_store
per class?
– Bergi
2 days ago
2
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
 |Â
show 1 more comment
up vote
23
down vote
accepted
up vote
23
down vote
accepted
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 the your functions by version, 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()
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 the your functions by version, 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()
edited 2 days ago
answered 2 days ago
Bi Rico
18.3k23457
18.3k23457
3
You probably wantf.__qualname__
to avoid conflict betweenProduct.function
andAmbassadorial.function
...
– Amadan
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separateversion_store
per class?
– Bergi
2 days ago
2
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
 |Â
show 1 more comment
3
You probably wantf.__qualname__
to avoid conflict betweenProduct.function
andAmbassadorial.function
...
– Amadan
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separateversion_store
per class?
– Bergi
2 days ago
2
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
3
3
You probably want
f.__qualname__
to avoid conflict between Product.function
and Ambassadorial.function
...– Amadan
2 days ago
You probably want
f.__qualname__
to avoid conflict between Product.function
and Ambassadorial.function
...– Amadan
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
OMG, this is my dream solution. Thank you for inspiring me!!!
– Timmy Lin
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
Python doesn't complain that there are two methods with the same name in a class? Which one does it use? (Yes I realise that the decorator returns the same function anyway, but Python doesn't know)
– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separate
version_store
per class?– Bergi
2 days ago
@Amadan Instead of using the qualified name, would it be possible to create a separate
version_store
per class?– Bergi
2 days ago
2
2
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
@Bergi methods are just members on the class. Each declaration replaces the last version, but it doesn't matter because, like you said, they're all the same :)
– Bi Rico
2 days ago
 |Â
show 1 more comment
up vote
7
down vote
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()
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
2
@TimmyLin In that case, you could have a base class, sayProduct
that holds all the duplicated content, then have aProductv1
andProductv2
that inherits it and just holds what is different. That way there's no duplicated code.
– Loocid
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
add a comment |Â
up vote
7
down vote
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()
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
2
@TimmyLin In that case, you could have a base class, sayProduct
that holds all the duplicated content, then have aProductv1
andProductv2
that inherits it and just holds what is different. That way there's no duplicated code.
– Loocid
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
add a comment |Â
up vote
7
down vote
up vote
7
down vote
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()
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()
edited 2 days ago
answered 2 days ago
Loocid
2,0721825
2,0721825
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
2
@TimmyLin In that case, you could have a base class, sayProduct
that holds all the duplicated content, then have aProductv1
andProductv2
that inherits it and just holds what is different. That way there's no duplicated code.
– Loocid
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
add a comment |Â
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
2
@TimmyLin In that case, you could have a base class, sayProduct
that holds all the duplicated content, then have aProductv1
andProductv2
that inherits it and just holds what is different. That way there's no duplicated code.
– Loocid
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
Actually, I used similar way to do version control before by creating multiple py files (e.g. v1, v2, v3), which is easiest but these files contain too many "duplicated content".. that's why I am trying to combine them into one CLASS. Thank you for your advice!
– Timmy Lin
2 days ago
2
2
@TimmyLin In that case, you could have a base class, say
Product
that holds all the duplicated content, then have a Productv1
and Productv2
that inherits it and just holds what is different. That way there's no duplicated code.– Loocid
2 days ago
@TimmyLin In that case, you could have a base class, say
Product
that holds all the duplicated content, then have a Productv1
and Productv2
that inherits it and just holds what is different. That way there's no duplicated code.– Loocid
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
And the MAIN reason is .. too many versions (but with small changes) in this product and it's still growing, so if I do this, the folder/files structure will become ugly eventually :|
– Timmy Lin
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Ah in that case my suggestion cant go any further. Good luck.
– Loocid
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
Exactly, the B plan is to use inherit from a main class. But I still want to know if there's any cool and elegant way to do this. If there isn't, I will mark you the best answer! thank you!
– Timmy Lin
2 days ago
add a comment |Â
up vote
5
down vote
As another option, you could go for some factory to create your class.
Create your versioned functions (note the self
parameter). This can be done in a different module. Also, add some collection to fetch the function based on the version number.
def func_10(self):
print('for version 1.0')
def func_20(self):
print('for version 2.0')
funcs = "1.0": func_10,
"2.0": func_20
Add a base class that contains the static parts of your implementation and a utility class to create your instances in:
class Product:
def __init__(self, version):
self.version = version
class ProductFactory(type):
@classmethod
def get_product_class(mcs, version):
# this will return an instance right away, due to the (version) in the end
return type.__new__(mcs, "Product_".format(version.replace(".","")), (Product,), "function": funcs.get(version))(version)
# if you want to return a class object to instantiate in your code omit the (version) in the end
Using this:
p1 = ProductFactory.get_product_class("1.0")
p2 = ProductFactory.get_product_class("2.0")
print(p1.__class__.__name__) # Product_10
p1.function() # for version 1.0
print(p1.function) # <bound method func_10 of <__main__.Product_10 object at 0x0000000002A157F0>>
print(p2.__class__.__name__) # Product_20
p2.function() # for version 2.0
print(p2.function) # <bound method func_20 of <__main__.Product_20 object at 0x0000000002A15860>>
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variablesp1, p2
, but this is absolutely a good answer. Thank you!
– Timmy Lin
2 days ago
1
@TimmyLin Actually, the functions are not separated into two variables.p1
andp2
are separate instances of subclasses ofProduct
, each with their own implementation offunction
based on theversion
(which is supposed to be yourclient.version
). Basically, this example builds the class with the implementation offunction
that is required for the given version instead of having one class implementing all possible 'versions' offunction
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)
– shmee
2 days ago
1
BTW: you could replaceProductFactor
with aProduct
class and define a__new__
method to do what theget_product_class
does. In this way the code has less boiler-plate.
– Bakuriu
2 days ago
add a comment |Â
up vote
5
down vote
As another option, you could go for some factory to create your class.
Create your versioned functions (note the self
parameter). This can be done in a different module. Also, add some collection to fetch the function based on the version number.
def func_10(self):
print('for version 1.0')
def func_20(self):
print('for version 2.0')
funcs = "1.0": func_10,
"2.0": func_20
Add a base class that contains the static parts of your implementation and a utility class to create your instances in:
class Product:
def __init__(self, version):
self.version = version
class ProductFactory(type):
@classmethod
def get_product_class(mcs, version):
# this will return an instance right away, due to the (version) in the end
return type.__new__(mcs, "Product_".format(version.replace(".","")), (Product,), "function": funcs.get(version))(version)
# if you want to return a class object to instantiate in your code omit the (version) in the end
Using this:
p1 = ProductFactory.get_product_class("1.0")
p2 = ProductFactory.get_product_class("2.0")
print(p1.__class__.__name__) # Product_10
p1.function() # for version 1.0
print(p1.function) # <bound method func_10 of <__main__.Product_10 object at 0x0000000002A157F0>>
print(p2.__class__.__name__) # Product_20
p2.function() # for version 2.0
print(p2.function) # <bound method func_20 of <__main__.Product_20 object at 0x0000000002A15860>>
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variablesp1, p2
, but this is absolutely a good answer. Thank you!
– Timmy Lin
2 days ago
1
@TimmyLin Actually, the functions are not separated into two variables.p1
andp2
are separate instances of subclasses ofProduct
, each with their own implementation offunction
based on theversion
(which is supposed to be yourclient.version
). Basically, this example builds the class with the implementation offunction
that is required for the given version instead of having one class implementing all possible 'versions' offunction
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)
– shmee
2 days ago
1
BTW: you could replaceProductFactor
with aProduct
class and define a__new__
method to do what theget_product_class
does. In this way the code has less boiler-plate.
– Bakuriu
2 days ago
add a comment |Â
up vote
5
down vote
up vote
5
down vote
As another option, you could go for some factory to create your class.
Create your versioned functions (note the self
parameter). This can be done in a different module. Also, add some collection to fetch the function based on the version number.
def func_10(self):
print('for version 1.0')
def func_20(self):
print('for version 2.0')
funcs = "1.0": func_10,
"2.0": func_20
Add a base class that contains the static parts of your implementation and a utility class to create your instances in:
class Product:
def __init__(self, version):
self.version = version
class ProductFactory(type):
@classmethod
def get_product_class(mcs, version):
# this will return an instance right away, due to the (version) in the end
return type.__new__(mcs, "Product_".format(version.replace(".","")), (Product,), "function": funcs.get(version))(version)
# if you want to return a class object to instantiate in your code omit the (version) in the end
Using this:
p1 = ProductFactory.get_product_class("1.0")
p2 = ProductFactory.get_product_class("2.0")
print(p1.__class__.__name__) # Product_10
p1.function() # for version 1.0
print(p1.function) # <bound method func_10 of <__main__.Product_10 object at 0x0000000002A157F0>>
print(p2.__class__.__name__) # Product_20
p2.function() # for version 2.0
print(p2.function) # <bound method func_20 of <__main__.Product_20 object at 0x0000000002A15860>>
As another option, you could go for some factory to create your class.
Create your versioned functions (note the self
parameter). This can be done in a different module. Also, add some collection to fetch the function based on the version number.
def func_10(self):
print('for version 1.0')
def func_20(self):
print('for version 2.0')
funcs = "1.0": func_10,
"2.0": func_20
Add a base class that contains the static parts of your implementation and a utility class to create your instances in:
class Product:
def __init__(self, version):
self.version = version
class ProductFactory(type):
@classmethod
def get_product_class(mcs, version):
# this will return an instance right away, due to the (version) in the end
return type.__new__(mcs, "Product_".format(version.replace(".","")), (Product,), "function": funcs.get(version))(version)
# if you want to return a class object to instantiate in your code omit the (version) in the end
Using this:
p1 = ProductFactory.get_product_class("1.0")
p2 = ProductFactory.get_product_class("2.0")
print(p1.__class__.__name__) # Product_10
p1.function() # for version 1.0
print(p1.function) # <bound method func_10 of <__main__.Product_10 object at 0x0000000002A157F0>>
print(p2.__class__.__name__) # Product_20
p2.function() # for version 2.0
print(p2.function) # <bound method func_20 of <__main__.Product_20 object at 0x0000000002A15860>>
answered 2 days ago


shmee
1,046511
1,046511
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variablesp1, p2
, but this is absolutely a good answer. Thank you!
– Timmy Lin
2 days ago
1
@TimmyLin Actually, the functions are not separated into two variables.p1
andp2
are separate instances of subclasses ofProduct
, each with their own implementation offunction
based on theversion
(which is supposed to be yourclient.version
). Basically, this example builds the class with the implementation offunction
that is required for the given version instead of having one class implementing all possible 'versions' offunction
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)
– shmee
2 days ago
1
BTW: you could replaceProductFactor
with aProduct
class and define a__new__
method to do what theget_product_class
does. In this way the code has less boiler-plate.
– Bakuriu
2 days ago
add a comment |Â
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variablesp1, p2
, but this is absolutely a good answer. Thank you!
– Timmy Lin
2 days ago
1
@TimmyLin Actually, the functions are not separated into two variables.p1
andp2
are separate instances of subclasses ofProduct
, each with their own implementation offunction
based on theversion
(which is supposed to be yourclient.version
). Basically, this example builds the class with the implementation offunction
that is required for the given version instead of having one class implementing all possible 'versions' offunction
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)
– shmee
2 days ago
1
BTW: you could replaceProductFactor
with aProduct
class and define a__new__
method to do what theget_product_class
does. In this way the code has less boiler-plate.
– Bakuriu
2 days ago
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variables
p1, p2
, but this is absolutely a good answer. Thank you!– Timmy Lin
2 days ago
cool! although it's a little bit complex, it could do the thing. however I am looking for a way that I don't need to separate functions into 2 variables
p1, p2
, but this is absolutely a good answer. Thank you!– Timmy Lin
2 days ago
1
1
@TimmyLin Actually, the functions are not separated into two variables.
p1
and p2
are separate instances of subclasses of Product
, each with their own implementation of function
based on the version
(which is supposed to be your client.version
). Basically, this example builds the class with the implementation of function
that is required for the given version instead of having one class implementing all possible 'versions' of function
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)– shmee
2 days ago
@TimmyLin Actually, the functions are not separated into two variables.
p1
and p2
are separate instances of subclasses of Product
, each with their own implementation of function
based on the version
(which is supposed to be your client.version
). Basically, this example builds the class with the implementation of function
that is required for the given version instead of having one class implementing all possible 'versions' of function
. However, I think you picked the best answer for your requirement, this was mereley added for completeness sake :)– shmee
2 days ago
1
1
BTW: you could replace
ProductFactor
with a Product
class and define a __new__
method to do what the get_product_class
does. In this way the code has less boiler-plate.– Bakuriu
2 days ago
BTW: you could replace
ProductFactor
with a Product
class and define a __new__
method to do what the get_product_class
does. In this way the code has less boiler-plate.– Bakuriu
2 days ago
add a comment |Â
up vote
4
down vote
In general, don't. Method overloading is discouraged in Python. If you have to differentiate on class level, read @Loocid's answer. I won't repeat his excellent post.
If you want in on a method level because the difference is small enough for that, try something like this:
class Product:
def method(self):
if self.version == "1.0":
return self._methodv1()
elif self.version == "2.0":
return self._methodv2()
else:
raise ValueError("No appropriate method for version ".format(self.version))
def _methodv1(self):
# implementation
def _methodv2(self):
# implementation
Note here:
- Use of methods starting with an underscore, to indicate those are
the implementation. - Keeping the methods nice and tidy without
contamination between the versions - Raising an error for unexpected versions (crash early and hard).
- In my not so humble opinion, this will be a lot clearer for other people reading your post than using decorators.
Or:
class Product:
def method_old(self):
# transform arguments to v2 method:
return self.method()
def method(self):
# implementation
- In case you want to totally deprecate previous useage, and want to drop version 1.0 support in the future.
- Be sure to give deprecation warnings, so to not surprise users of a library with sudden changes.
- Arguably the better solution if nobody else uses your code.
I get the vibe my first method would be more suitable to your problem at hand, but I wanted to include the second for posterity. If you edit your code 10 years from now, that one will make you happier. If you edit code using the current code tomorrow, the first method will make you happier.
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
add a comment |Â
up vote
4
down vote
In general, don't. Method overloading is discouraged in Python. If you have to differentiate on class level, read @Loocid's answer. I won't repeat his excellent post.
If you want in on a method level because the difference is small enough for that, try something like this:
class Product:
def method(self):
if self.version == "1.0":
return self._methodv1()
elif self.version == "2.0":
return self._methodv2()
else:
raise ValueError("No appropriate method for version ".format(self.version))
def _methodv1(self):
# implementation
def _methodv2(self):
# implementation
Note here:
- Use of methods starting with an underscore, to indicate those are
the implementation. - Keeping the methods nice and tidy without
contamination between the versions - Raising an error for unexpected versions (crash early and hard).
- In my not so humble opinion, this will be a lot clearer for other people reading your post than using decorators.
Or:
class Product:
def method_old(self):
# transform arguments to v2 method:
return self.method()
def method(self):
# implementation
- In case you want to totally deprecate previous useage, and want to drop version 1.0 support in the future.
- Be sure to give deprecation warnings, so to not surprise users of a library with sudden changes.
- Arguably the better solution if nobody else uses your code.
I get the vibe my first method would be more suitable to your problem at hand, but I wanted to include the second for posterity. If you edit your code 10 years from now, that one will make you happier. If you edit code using the current code tomorrow, the first method will make you happier.
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
add a comment |Â
up vote
4
down vote
up vote
4
down vote
In general, don't. Method overloading is discouraged in Python. If you have to differentiate on class level, read @Loocid's answer. I won't repeat his excellent post.
If you want in on a method level because the difference is small enough for that, try something like this:
class Product:
def method(self):
if self.version == "1.0":
return self._methodv1()
elif self.version == "2.0":
return self._methodv2()
else:
raise ValueError("No appropriate method for version ".format(self.version))
def _methodv1(self):
# implementation
def _methodv2(self):
# implementation
Note here:
- Use of methods starting with an underscore, to indicate those are
the implementation. - Keeping the methods nice and tidy without
contamination between the versions - Raising an error for unexpected versions (crash early and hard).
- In my not so humble opinion, this will be a lot clearer for other people reading your post than using decorators.
Or:
class Product:
def method_old(self):
# transform arguments to v2 method:
return self.method()
def method(self):
# implementation
- In case you want to totally deprecate previous useage, and want to drop version 1.0 support in the future.
- Be sure to give deprecation warnings, so to not surprise users of a library with sudden changes.
- Arguably the better solution if nobody else uses your code.
I get the vibe my first method would be more suitable to your problem at hand, but I wanted to include the second for posterity. If you edit your code 10 years from now, that one will make you happier. If you edit code using the current code tomorrow, the first method will make you happier.
In general, don't. Method overloading is discouraged in Python. If you have to differentiate on class level, read @Loocid's answer. I won't repeat his excellent post.
If you want in on a method level because the difference is small enough for that, try something like this:
class Product:
def method(self):
if self.version == "1.0":
return self._methodv1()
elif self.version == "2.0":
return self._methodv2()
else:
raise ValueError("No appropriate method for version ".format(self.version))
def _methodv1(self):
# implementation
def _methodv2(self):
# implementation
Note here:
- Use of methods starting with an underscore, to indicate those are
the implementation. - Keeping the methods nice and tidy without
contamination between the versions - Raising an error for unexpected versions (crash early and hard).
- In my not so humble opinion, this will be a lot clearer for other people reading your post than using decorators.
Or:
class Product:
def method_old(self):
# transform arguments to v2 method:
return self.method()
def method(self):
# implementation
- In case you want to totally deprecate previous useage, and want to drop version 1.0 support in the future.
- Be sure to give deprecation warnings, so to not surprise users of a library with sudden changes.
- Arguably the better solution if nobody else uses your code.
I get the vibe my first method would be more suitable to your problem at hand, but I wanted to include the second for posterity. If you edit your code 10 years from now, that one will make you happier. If you edit code using the current code tomorrow, the first method will make you happier.
answered 2 days ago
Jacco van Dorp
1595
1595
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
add a comment |Â
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
Thank you for the honest advice! Everyone here did help me a lot, it's struggle to say who's solution is the best. Let's say.. the project I am working on is .. extremely huge, we want the version difference can be listed out very CLEARLY and can be maintained easily. That's why I insist to use decorator to do this due to it's the clearest and beauty one. To be honest, if I am working on another smaller project, I will definitely choose your 2nd options and also @Loocid's one.
– Timmy Lin
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
We can only ever look at a small part at the time - in a huge project, only you can pick the right option, due to the style of the rest of the project. Best we can do is list the possibilities. Good luck with it !
– Jacco van Dorp
2 days ago
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Designing a new framework for development is hard, I really like your first suggestion and I have discussed that with team, maybe there's a chance we will go that way or @BartoszKP's way. Both are excellent.
– Timmy Lin
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
Glad that you have use for it :)
– Jacco van Dorp
yesterday
add a comment |Â
up vote
0
down vote
You can use decorators for this
def v_decorate(func):
def func_wrapper(name):
return func(name)
return func_wrapper
And
@v_decorate
def get_version(name):
return "for version 0 ".format(name)
You can call it
get_version(1.0)
'for version 1.0 '
get_version(2.0)
'for version 2.0 '
I am sorry, I am not sure if I understand this correctly. Thev_decorate
is to add an extra argumentname
to the original function? don't understand how to combine this to my same name functions.. Orz
– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version tov_decorate
and put into called function is kinda extra steps. Modify my function tofunction(self): print(f'for version self.version')
can do the exactly same thing without decorator..
– Timmy Lin
2 days ago
4
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
add a comment |Â
up vote
0
down vote
You can use decorators for this
def v_decorate(func):
def func_wrapper(name):
return func(name)
return func_wrapper
And
@v_decorate
def get_version(name):
return "for version 0 ".format(name)
You can call it
get_version(1.0)
'for version 1.0 '
get_version(2.0)
'for version 2.0 '
I am sorry, I am not sure if I understand this correctly. Thev_decorate
is to add an extra argumentname
to the original function? don't understand how to combine this to my same name functions.. Orz
– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version tov_decorate
and put into called function is kinda extra steps. Modify my function tofunction(self): print(f'for version self.version')
can do the exactly same thing without decorator..
– Timmy Lin
2 days ago
4
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
add a comment |Â
up vote
0
down vote
up vote
0
down vote
You can use decorators for this
def v_decorate(func):
def func_wrapper(name):
return func(name)
return func_wrapper
And
@v_decorate
def get_version(name):
return "for version 0 ".format(name)
You can call it
get_version(1.0)
'for version 1.0 '
get_version(2.0)
'for version 2.0 '
You can use decorators for this
def v_decorate(func):
def func_wrapper(name):
return func(name)
return func_wrapper
And
@v_decorate
def get_version(name):
return "for version 0 ".format(name)
You can call it
get_version(1.0)
'for version 1.0 '
get_version(2.0)
'for version 2.0 '
answered 2 days ago
Richard Rublev
2,78331832
2,78331832
I am sorry, I am not sure if I understand this correctly. Thev_decorate
is to add an extra argumentname
to the original function? don't understand how to combine this to my same name functions.. Orz
– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version tov_decorate
and put into called function is kinda extra steps. Modify my function tofunction(self): print(f'for version self.version')
can do the exactly same thing without decorator..
– Timmy Lin
2 days ago
4
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
add a comment |Â
I am sorry, I am not sure if I understand this correctly. Thev_decorate
is to add an extra argumentname
to the original function? don't understand how to combine this to my same name functions.. Orz
– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version tov_decorate
and put into called function is kinda extra steps. Modify my function tofunction(self): print(f'for version self.version')
can do the exactly same thing without decorator..
– Timmy Lin
2 days ago
4
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
I am sorry, I am not sure if I understand this correctly. The
v_decorate
is to add an extra argument name
to the original function? don't understand how to combine this to my same name functions.. Orz– Timmy Lin
2 days ago
I am sorry, I am not sure if I understand this correctly. The
v_decorate
is to add an extra argument name
to the original function? don't understand how to combine this to my same name functions.. Orz– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version to
v_decorate
and put into called function is kinda extra steps. Modify my function to function(self): print(f'for version self.version')
can do the exactly same thing without decorator..– Timmy Lin
2 days ago
Doing this is nothing different from the first example I wrote in description.. passing version to
v_decorate
and put into called function is kinda extra steps. Modify my function to function(self): print(f'for version self.version')
can do the exactly same thing without decorator..– Timmy Lin
2 days ago
4
4
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
I don't see what this decorator actually accomplishes ?
– Jacco van Dorp
2 days ago
add a comment |Â
up vote
0
down vote
I'm not a python developer but I can't help but wonder why you don't just do something like this:
class Product(object):
def __init__(self, version):
self.version = version
def function(self):
print('for version ' + self.version)
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
add a comment |Â
up vote
0
down vote
I'm not a python developer but I can't help but wonder why you don't just do something like this:
class Product(object):
def __init__(self, version):
self.version = version
def function(self):
print('for version ' + self.version)
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I'm not a python developer but I can't help but wonder why you don't just do something like this:
class Product(object):
def __init__(self, version):
self.version = version
def function(self):
print('for version ' + self.version)
I'm not a python developer but I can't help but wonder why you don't just do something like this:
class Product(object):
def __init__(self, version):
self.version = version
def function(self):
print('for version ' + self.version)
answered 2 days ago
Jack
560415
560415
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
add a comment |Â
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
Because this is just a example that make ppl easier to understand what I was trying to do. The function is not only printing things but do a lot of operations. Actually I don't even need to self.version to be passed into function method, I just need it to locate which function I want to load while program is running.
– Timmy Lin
yesterday
add a comment |Â
up vote
0
down vote
Or you can do, dict.get
to call a function and do print
in lambda
if nothing is right:
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Example:
class Product(object):
def __init__(self,version):
self.version = version
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Product('1.0').function()
Product('2.0').function()
Product('3.0').function()
Output:
for version 1.0
for version 2.0
function not support 3.0
add a comment |Â
up vote
0
down vote
Or you can do, dict.get
to call a function and do print
in lambda
if nothing is right:
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Example:
class Product(object):
def __init__(self,version):
self.version = version
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Product('1.0').function()
Product('2.0').function()
Product('3.0').function()
Output:
for version 1.0
for version 2.0
function not support 3.0
add a comment |Â
up vote
0
down vote
up vote
0
down vote
Or you can do, dict.get
to call a function and do print
in lambda
if nothing is right:
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Example:
class Product(object):
def __init__(self,version):
self.version = version
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Product('1.0').function()
Product('2.0').function()
Product('3.0').function()
Output:
for version 1.0
for version 2.0
function not support 3.0
Or you can do, dict.get
to call a function and do print
in lambda
if nothing is right:
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Example:
class Product(object):
def __init__(self,version):
self.version = version
def func_1(self):
print('for version 1.0')
def func_2(self):
print('for version 2.0')
def function(self):
funcs = "1.0": self.func_1,
"2.0": self.func_2
funcs.get(self.version,lambda: print(f'function not support self.version'))()
Product('1.0').function()
Product('2.0').function()
Product('3.0').function()
Output:
for version 1.0
for version 2.0
function not support 3.0
answered yesterday


U9-Forward
4,9652428
4,9652428
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52252054%2fsame-name-functions-in-same-class-elegant-way-to-determine-which-to-call%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
The "standard" way to solve this would be to have
ProductV1
andProductV2
then yourProduct
class simply has an_impl
attribute that is assigned to aProductV<version>
and all the methods are forwarded likedef function(self): return self._impl.function()
. In python you could even avoid defining them by using__getattr__
. Also:ProductVX
would simply define the basic operations and you can put inProduct
the facade methods that you can build on top of the basic methods.– Bakuriu
2 days ago
I forgot to say: by "standard solution" I mean: this is what you'd do in most programming languages where you cannot use stuff like decorators for example. Also: if you have big classes using decorators makes your class quite big and hard to work with. It's easier to separate completely the version-specific implementations.
– Bakuriu
2 days ago