首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用__getattr__()按需创建成员方法

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

Stack Overflow用户
提问于 2014-06-17 13:34:05
回答 1查看 176关注 0票数 2

给定一个类MyClass(object),我如何使用某种模板和MyClass.__getattr__机制以编程方式定义类成员方法?我在想一件事

代码语言:javascript
复制
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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-17 13:41:35

您不需要重新定义__getattr__ (实际上,您通常不应该这样做)。Python是一种后期绑定语言。这意味着您可以在任何时候(甚至在运行时动态地)为类中的名称赋值,它们现在将存在。

因此,在您的情况下,您可以简单地做:

代码语言:javascript
复制
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)

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

代码语言:javascript
复制
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))

示例:

代码语言:javascript
复制
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的模板创建位,因为我使用传递函数,而不是简单的名称作为参数。但是,您应该能够看到如何扩展该示例以满足您的需要,因为模板创建部分有点超出了最初问题的范围,即如何将方法动态绑定到类。

一个重要的注意事项:这只影响--的单个实例如果要影响所有实例,请更改此问题。虽然我认为在这种情况下使用混合班会更好。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24265269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档