如何使用 metaclass 添加方法
我想知道怎么通过元类给一个类添加实例方法(是的,我确实需要用元类)。下面的代码有点效果,但函数的名字还是“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'
我的问题是,有些库的代码实际上会用到这个函数名,结果找不到Foo实例的“bar”方法。我可以这样做:
dict["foobar"] = types.FunctionType(bar.func_code, {}, "foobar")
还有一种叫做types.MethodType的东西,但我需要一个还不存在的实例来使用它。我是不是漏掉了什么?
2 个回答
3
我觉得你想做的事情是这样的:
>>> 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'
现在你可以把 Foo
对象传给一个需要 Foo
实例有一个叫 foobar
方法的库了。
不过很遗憾的是,(1) 我不知道怎么使用 metaclass(元类),(2) 我也不太确定我理解了你的问题,但我希望这些能对你有帮助。
请注意,func_name
这个功能只有在 Python 2.4 及以上版本中才能使用。
17
试着以这种方式动态地扩展基类,这样你就可以利用方法解析顺序(mro),而且这些方法是真正的可用方法:
Python 3:
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(metaclass=MetaFoo):
...
f = Foo()
f.bar()
print(f.bar.__qualname__)
Python 2:
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