Python:允许没有特别定义的方法被称为ala-getattr__

2024-09-30 20:36:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试编写一个Python类,它可以执行以下操作:

c = MyClass()
a = c.A("a name for A") # Calls internally c.create("A", "a name for A")
b = c.B("a name for B") # Calls internally c.create("B", "a name for B")

A和B可以是任何东西(它们是在数据库中定义的,但我不想在代码中显式地定义它们)

一个棘手的解决方法是执行以下操作:

^{pr2}$

当用户调用类似以下内容时,这将起作用:

a = c.A("nameA")
b = c.B("nameB")

但是,在存储函数指针而不被调用的情况下,它会崩溃:

aFunc = c.A
bFunc = c.B
aFunc("nameA") # Is actually calling c.create("B", "nameA"),
               # as c.B was the last __getattr__() call
bFunc("nameB")

有什么建议吗?在

谢谢

编辑:我似乎刚刚想出了这个办法,但菲利普有一个更优雅的解决方案。。。。在

我的解决方案是:

class MyClassCreator():
    def __init__(self, origClass, itemType):
        self.origClass = origClass
        self.itemType = itemType

    def create_wrapper(self, name):
        return self.origClass.create(self.itemType, name)

class MyClass():
    def __init__(self):
        self.createItem = ""

    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def __getattr__(self, attrName):
        return MyClassCreator(self, attrName).create_wrapper

我最终使用的版本是:(我不知道是否可以使用lambda函数…)

def __getattr__(self, attrName):
    def find_entity_wrapper(*args, **kwargs):
        return self.find_entity(attrName, *args, **kwargs)

    return find_entity_wrapper

Tags: nameselfforreturndefcreatemyclassfind
2条回答

您可以通过简化:

class MyClass():

    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def __getattr__(self, attrName):
        return lambda x: self.create(attrName, x)

c = MyClass()
a = c.A("nameA")
b = c.B("nameB")


af = c.A
bf = c.B
af("nameA")
bf("nameB")

印刷品:

^{pr2}$

使__getattr__返回本地包装函数:

class MyClass(object):
    def create(self, itemType, itemName):
        print "Creating item %s with name %s" % (itemType, itemName)

    def __getattr__(self, attrName):
        def create_wrapper(name):
            self.create(attrName, name)
        return create_wrapper

还有其他方法可以创建包装器函数。在这种情况下,最简单的方法是使用functools.partial

^{pr2}$

这将自动将所有剩余的参数传递给包装好的函数。在

相关问题 更多 >