【发布时间】:2014-03-20 16:08:23
【问题描述】:
假设我有一个 python 类
class Foo(object):
def method1(self, x):
print("method1 called with %s" %(x,))
def method2(self, x):
print("method2 called with %s" %(x,))
和一个装饰器
def myDecorator(func):
newFunc = someModificationOf(func)
return newFunc
我希望能够将Foo 子类化,并且在子类定义中以某种方式表明我希望将myDecorator 应用于从Foo 继承的某些方法子集。例如,我的子类可能喜欢
class Baz(Foo):
methodsToDecorate = ['method2']
这可能吗?
我尝试了什么:
我认为我可以使用元类来做到这一点:
class Baz(Foo):
__metaclass__ = Meta
methodsToDecorate = ['method2']
class Meta(type):
def __new__(cls, name, bases, d):
for m in d['methodsToDecorate']:
d[m] = myDecorator(d[m])
return type(name, bases, d)
但是,它不起作用,因为'method2' 不在传递给元类的__new__ 方法的字典中,所以我们得到了KeyError。我喜欢使用元类的想法,因为它允许装饰器操作函数,而不是方法,这似乎是一个很好的简化。
【问题讨论】:
-
我不认为你真的想装饰基类方法只是因为创建了一些子类,是吗?这会影响基类的每个实例,以及它的所有独立子类,这会导致代码非常混乱。您是否只想用超类方法的修饰版本覆盖子类中的方法?因为这要简单得多,也更明智。
-
附带说明,您使用的是 Python 2 风格的元类,但 Python 3 风格的
print方法。您实际使用的是哪种语言? -
我使用的是 python 2.7,但习惯于使用 Python 3.x 打印语句,因为它们都适用。
-
好的,很酷。只是想检查一下。我见过有人问“为什么我的元类不起作用”,因为他们试图在 3.x 中使用
__metaclass__...
标签: python decorator metaclass