python - 使用 __getattr__() 按需创建成员方法

标签 python class oop member getattr

给定一个类 MyClass(object),如何使用某些模板和 MyClass.__getattr__ 机制以编程方式定义类成员方法?我正在考虑类似的事情

class MyClass(object):
    def __init__(self, defaultmembers, members):
        # defaultmembers is a list
        # members is a dict
        self._defaultmembers = defaultmembers
        self._members = members

    # some magic spell creating a member function factory

    def __getattr__(self):
        # some more magic

def f_MemberB():
    pass

C = MyClass(defaultmembers=["MemberA"], members=dict(MemberB=f_MemberB)
C.MemberA()  # should be a valid statement
C.MemberB()  # should also be a valid statement
C.MemberC()  # should raise an AttributeError

C.MemberA 应该是从类内部的某些模板机制自动创建的方法,C.MemberB 应该是函数 f_MemberB .

最佳答案

您不需要重新定义__getattr__(事实上您通常不应该这样做)。 Python 是 late binding语言。这意味着您可以随时简单地为类中的名称分配值(甚至在运行时动态地),并且它们现在将存在。

因此,就您的情况而言,您可以简单地执行以下操作:

class MyClass(object):
    def __init__(self, defaultmembers, members):
        # defaultmembers is a list
        # members is a dict
        for func in defaultmembers:
            setattr(self, func.__name__, func)
        for name, func in members.items():
            setattr(self, name, func)

请注意,这实际上不会将方法绑定(bind)到类(它不会将self作为其第一个参数)。如果这就是您想要的,您需要使用 MethodType来自 types 的函数,如下所示:

from types import MethodType

class MyClass(object):
    def __init__(self, defaultmembers, members):
        # defaultmembers is a list
        # members is a dict
        for func in defaultmembers:
            name =  func.__name__
            setattr(self, name , func)
            setattr(self, name , MethodType(getattr(self, name), self))
        for name, func in members.items():
            setattr(self, name, func)
            setattr(self, name , MethodType(getattr(self, name), self))

示例:

def def_member(self):
    return 1

def key_member(self):
    return 2

>>> test = MyClass([def_member], {'named_method':key_member})
>>> test.def_member()
1
>>> test.named_method()
2

您还可以使用 *args**kwargs 使 init 方法稍微不那么尴尬,因此示例将是 test = MyClass( def_member,named_member = key_member)如果您知道此类的构造函数不会有任何其他参数。

显然,我省略了 defaultmembers 的模板创建位,因为我使用传递函数而不是简单的名称作为参数。但是您应该能够看到如何扩展该示例以满足您的需求,因为模板创建部分有点超出了原始问题的范围,即如何将方法动态绑定(bind)到类。

重要提示:这只影响MyClass的单个实例。如果您想影响所有实例,请更改问题。虽然我会认为使用 mixin class在这种情况下会更好。

关于python - 使用 __getattr__() 按需创建成员方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24265269/

相关文章:

python - 从简单的三列文本文件创建矩阵

c++ - 我不明白我为这个程序得到的输出。

javascript - 如何在此 javascript 中使用 html 标签?

python - PySpark 以密集向量形式读入文本文件

python - 在 Pandas 中执行类似 excel 的计数

java - 受限玻尔兹曼机中的自由能近似方程

c++返回类型具有当前类类型的指针

c++ - 指向对象表的指针

model-view-controller - MVC 中的模型到底是什么

java - 一个类文件可以实现多少接口(interface)