如何修饰一个类的所有功能而不用为每个方法一遍又一遍地键入它? [英] How to decorate all functions of a class without typing it over and over for each method?
问题描述
让我们说我的课程有很多方法,我想在每个方法上应用我的装饰器,稍后当我添加新方法时,我想应用相同的装饰器,但是我不想在上方写@mydecorator方法声明一直都在吗?
Lets say my class has many methods, and I want to apply my decorator on each one of them, later when I add new methods, I want the same decorator to be applied, but I dont want to write @mydecorator above the method declaration all the time?
如果我研究 __ call __
是正确的方法吗?
If I look into __call__
is that the right way to go?
重要提示:以下示例似乎在解决与原始问题不同的问题。
IMPORTANT: the example below appears to be solving a different problem than the original question asked about.
编辑:我想演示这种方式,这类似于我的问题,以后使用注释中提到的mixin找到这个问题的任何人都可以。
Id like to show this way, which is a similar solution to my problem for anyobody finding this question later, using a mixin as mentioned in the comments.
class WrapinMixin(object):
def __call__(self, hey, you, *args):
print 'entering', hey, you, repr(args)
try:
ret = getattr(self, hey)(you, *args)
return ret
except:
ret = str(e)
raise
finally:
print 'leaving', hey, repr(ret)
然后您可以在另一个
class Wrapmymethodsaround(WrapinMixin):
def __call__:
return super(Wrapmymethodsaround, self).__call__(hey, you, *args)
推荐答案
使用遍历类属性并装饰可调用对象的函数装饰类。如果您有可能恰好可以调用的类变量,并且还会修饰嵌套的类(请感谢Sven Marnach指出这一点),那么这可能是错误的做法,但是通常这是一个非常干净且简单的解决方案。示例实现(请注意,这不会排除可能不需要的特殊方法( __ init __
等):
Decorate the class with a function that walks through the class's attributes and decorates callables. This may be the wrong thing to do if you have class variables that may happen to be callable, and will also decorate nested classes (credits to Sven Marnach for pointing this out) but generally it's a rather clean and simple solution. Example implementation (note that this will not exclude special methods (__init__
etc.), which may or may not be desired):
def for_all_methods(decorator):
def decorate(cls):
for attr in cls.__dict__: # there's propably a better way to do this
if callable(getattr(cls, attr)):
setattr(cls, attr, decorator(getattr(cls, attr)))
return cls
return decorate
像这样使用:
@for_all_methods(mydecorator)
class C(object):
def m1(self): pass
def m2(self, x): pass
...
在Python 3.0和3.1中, callable
不存在。它在Python 2.x中一直存在,并在Python 3.2中作为 isinstance(x,collections.Callable)
的包装器返回,因此您可以使用它(或定义自己的在这些版本中使用<)进行可调用
替换。
In Python 3.0 and 3.1, callable
does not exist. It existed since forever in Python 2.x and is back in Python 3.2 as wrapper for isinstance(x, collections.Callable)
, so you can use that (or define your own callable
replacement using this) in those versions.
这篇关于如何修饰一个类的所有功能而不用为每个方法一遍又一遍地键入它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!