Inheritance of dynamically added methods
I have the following class ClassA
for which I am dynamically creating a method that returns a version of string
another method:
# module_a.py
class ClassA(object):
def width(self):
return 5
def height(self):
return 10
@classmethod
def add_str_method(cls, name):
method = getattr(cls, name)
def str_method(self):
return str(method(self))
setattr(cls, '{0}_str'.format(name), str_method)
for name in ['width', 'height']:
ClassA.add_str_method(name)
This part works great unless I subclass ClassA
in another module. But when I do it like in the example below, the dynamically added methods are not inherited.
# module_b.py
from module_a import ClassA
class ClassB(ClassA):
pass
How could you add methods dynamically so that they are automatically inherited by subclasses?
source to share
First you need to declare add_str_method
as @classmethod
if you want to dynamically update the class A
(not just the instance A
).
# file a.py
class A(object):
def __init__(self, a=5):
self._a = a
def a(self):
return self._a
@classmethod
def add_str_method(cls, name):
def str_method(self):
return str(getattr(self, name)())
setattr(cls, '{0}_str'.format(name), str_method)
for name in ['a']:
A.add_str_method(name)
To access a method A
from, A
and thus a variable _a
bound to a specific instance, the method str
must be constrained self
, note the following lines:
def str_method(self):
return str(getattr(self, name)())
Now, with this script tested, it works as expected:
# file b.py
from a import A
class B(A):
pass
print(B(10).a_str()) # prints '10'
source to share
You will need to add a procedure to initialization ( __init__
) classA
:
class ClassA(object):
def __init__(self):
for name in ['width', 'height']:
self.add_str_method(name)
def width(self):
return 5
def height(self):
return 10
def add_str_method(cls, name):
method = getattr(self, name)
def str_method(self):
return str(method())
setattr(cls, '{0}_str'.format(name), str_method)
Now let's do
from module_a import ClassA
class ClassB(ClassA):
pass
print(dir(ClassB))
gives:
>>> ... 'height', 'width']
source to share