@deco
def foo():
# blah
与此相同:
def foo():
# blah
foo = deco(foo)
您可以根据需要随时执行相同的操作,而无需使用@
语法,只需将函数替换为所需的任何内容即可。因此,在__init__
任何其他地方,您都可以循环浏览所有方法,并用替换每个方法smilewarmly(meth)
。
但是,__init__
在类创建后,这样做比在in中执行更有意义。您可以使用一个元类,或更简单地使用一个类装饰器来做到这一点:
def smileDeco(func):
def wrapped(*args, **kw):
print ":-)"
func(*args, **kw)
return classmethod(wrapped)
def makeSmiley(cls):
for attr, val in cls.__dict__.iteritems():
if callable(val) and not attr.startswith("__"):
setattr(cls, attr, smileDeco(val))
return cls
@makeSmiley
class Foo(object):
def sayStuff(self):
print "Blah blah"
>>> Foo().sayStuff()
:-)
Blah blah
在此示例中,我将类方法装饰放入smileDeco
装饰器中。您也可以将其放入makeSmiley
以便makeSmiley
返回smileDeco(classmethod(val))
。(您要采用哪种方式取决于微笑装饰器与类方法之间的紧密联系。)这意味着您不必@classmethod
在类内部使用。
同样,当然,在循环中,makeSmiley
您可以包含要确定的任何逻辑(例如,基于方法的名称)是否用微笑行为包装。
请注意,如果您真的想@classmethod
在类内部手动使用,则必须多加注意,因为通过类访问的类方法__dict__
是不可调用的。因此,您必须专门检查对象是否为类方法对象,而不是仅检查它是否可调用。