10

如何使用元类向类添加实例方法(是的,我确实需要使用元类)?以下类型的作品,但 func_name 仍将是“foo”:

def bar(self):
    print "bar"

class MetaFoo(type):
    def __new__(cls, name, bases, dict):
        dict["foobar"] = bar
        return type(name, bases, dict)

class Foo(object):
    __metaclass__ = MetaFoo

>>> f = Foo()
>>> f.foobar()
bar
>>> f.foobar.func_name
'bar'

我的问题是一些库代码实际上使用了 func_name 并且后来找不到 Foo 实例的 'bar' 方法。我可以做:

dict["foobar"] = types.FunctionType(bar.func_code, {}, "foobar")

还有 types.MethodType,但我需要一个尚不存在的实例来使用它。我在这里错过了什么吗?

4

2 回答 2

15

尝试以可以利用 mro 的方式动态扩展基础,并且这些方法是实际方法:

class Parent(object):
    def bar(self):
        print "bar"

class MetaFoo(type):
    def __new__(cls, name, bases, dict):
        return type(name, (Parent,) + bases, dict)

class Foo(object):
    __metaclass__ = MetaFoo

if __name__ == "__main__":
    f = Foo()
    f.bar()
    print f.bar.func_name
于 2008-09-15T19:01:27.850 回答
2

我想你想要做的是:

>>> class Foo():
...   def __init__(self, x):
...     self.x = x
... 
>>> def bar(self):
...   print 'bar:', self.x
... 
>>> bar.func_name = 'foobar'
>>> Foo.foobar = bar
>>> f = Foo(12)
>>> f.foobar()
bar: 12
>>> f.foobar.func_name
'foobar'

现在您可以自由地将Foos 传递给期望Foo实例具有名为 的方法的库foobar

不幸的是,(1)我不知道如何使用元类和(2)我不确定我是否正确阅读了你的问题,但我希望这会有所帮助。

请注意,func_name它只能在 Python 2.4 及更高版本中分配。

于 2008-09-15T18:57:29.750 回答