Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/356.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 动态添加方法的继承_Python_Class - Fatal编程技术网

Python 动态添加方法的继承

Python 动态添加方法的继承,python,class,Python,Class,我有以下类ClassA,为此我动态创建了一个方法,返回另一个方法的string版本: # 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)

我有以下类
ClassA
,为此我动态创建了一个方法,返回另一个方法的
string
版本:

# 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)
只要我不在不同的模块中对
ClassA
进行子类化,这一部分就可以很好地工作。但是当我这样做的时候,就像下面的例子一样,动态添加的方法不会被继承

# module_b.py
from module_a import ClassA

class ClassB(ClassA):
    pass

动态添加方法以便子类自动继承方法的正确方法是什么?

您必须将过程添加到
classA
的初始化(
\uuuuu init\uuuu
)中:

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)
现在做

from module_a import ClassA

class ClassB(ClassA):
    pass

print(dir(ClassB))
给出:

>>> ...  'height', 'width']

如果要动态更新类
a
(而不仅仅是
a
的实例),首先必须将
add\u str\u method
声明为
@classmethod

为了从
a
访问
a
方法,从而访问附加到特定实例的变量
\u a
str
方法必须绑定到
self
,请注意以下几行:

def str_method(self):
    return str(getattr(self, name)())
现在,使用此测试脚本,它可以按预期工作:

# file b.py
from a import A

class B(A):
    pass

print(B(10).a_str()) # prints '10'

我尝试运行您的第一个代码块,但出现以下错误:
TypeError:unbound method add\u str\u method()必须以ClassA实例作为第一个参数调用(改为got str instance)
对不起,我在代码中出错了。我现在已经更正了。您更新的问题对于我的建议是有效的。但我相信一定有更好的办法。例如,如果我初始化1M对象,它们中的每一个都会在初始化时添加这些方法,而不是在类级别进行一次。此外,以类似的方式定义类方法也很有用,这在
\uuu init\uuu()
方法中是无法做到的。不过,你的问题有点含糊。根据上面的方案,还可以决定将
name
作为输入参数。然后你可以控制初始化。
# file b.py
from a import A

class B(A):
    pass

print(B(10).a_str()) # prints '10'