How to save code duplication in the following scenario ?
say Aand B are two classes having a common function(say) name
class A(object):
name = 'foo'
@property
def name(self): # the common function
return self.name
similarly B
class B(object):
name = 'bar'
@property
def name(self):
return self.name
One way would be to make a class from which both of them inherit from, and define name there.
Any good alternatives ?
-
1Also see stackoverflow.com/questions/4139508.FMc– FMc2013年07月16日 03:18:50 +00:00Commented Jul 16, 2013 at 3:18
5 Answers 5
If you're really determined to avoid inheritance, just define a function outside of either class:
def get_name(object):
return object.name
Comments
class A(object):
name = 'foo'
def get_name(self): # the common function
return self.name
class B(A):
pass
In this case B would inherit from A
Comments
Is there a reason you can't have B inherit from A?
class B(A):
name = 'bar'
Since you are decorating name with @property, I am assuming you want this to be an instance variable. If you want this to return a more private variable, let's call it _name, you have to do:
class A(object):
def __init__(self):
self._name = 'foo'
@property
def name(self):
return self._name
You can't have both a variable and a function have the same name, since the latter will simply override the former. If you want a base class that takes care of this, it would look like this:
class HasName(object):
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
class A(HasName):
def __init__(self):
self._name = 'foo'
class B(HasName):
def __init__(self):
self._name = 'bar'
You can also call the constructor in HasName.
Comments
Assuming self.name stands in for a more complex method, the easiest way to cut down on duplicated code is to move the function out to the module and have it take an arbitrary object as a parameter. Then, if you still want to tie the method directly to the class, you can add a short method that dispatches to the module function.
def _name(obj):
return obj.name
class A(object):
# ...
@property
def name(self):
return _name(self)
class B(object):
# ...
@property
def name(self):
return _name(self)
Note that this will not work well if A.name and B.name have completely different behaviors. If the _name function starts checking the type of the object given, reconsider whether you really want to abstract that functionality in the first place.