如何使用元类添加方法
时间:2020-03-05 18:54:10 来源:igfitidea点击:
如何使用元类向类添加实例方法(是的,我确实需要使用元类)?可以进行以下工作,但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")
还有type.MethodType,但是我需要一个尚不存在的实例来使用它。我在这里想念东西吗?
解决方案
回答
我认为我们想做的是这样的:
>>> 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)我不知道如何使用元类,(2)我不确定我是否正确阅读了问题,但是希望对我们有所帮助。
请注意,func_name
仅可在Python 2.4及更高版本中分配。
回答
尝试动态扩展基础,以便可以利用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