python教程—如何修饰类的所有函数而不需要为每个方法反复输入?(复制)-Python实用宝典

python教程—如何修饰类的所有函数而不需要为每个方法反复输入?(复制)

这个问题已经有了一个答案:假设我班有很多方法,我想申请我的装饰在每个其中之一,后来当我添加新的方法,我希望同样的装饰应用,但我不想写@mydecorator方法声明以上所有的时间吗?

这个问题已经有了答案:

假设我的类有很多方法,我想在每个方法上应用我的装饰器,稍后当我添加新方法时,我希望应用相同的装饰器,但我不想总是在方法声明上面写@mydecorator ?

如果我研究一下……call__,这是正确的方法吗?

IMPORTANT:下面的例子似乎是在解决一个与最初的问题不同的问题。

EDIT: Id想这样显示,这是我的问题的一个类似的解决方案,任何后来发现这个问题的人都可以使用mixin,就像评论中提到的那样。

    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__等):

    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。它在python2中一直存在。在Python 3.2中,它是isinstance(x, collections.Callable)的包装器,所以您可以在这些版本中使用它(或者使用它定义您自己的可调用替换)。

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
2

发表评论