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?

+3


source to share


2 answers


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'

      

+2


source


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']

      

0


source







All Articles