如何修饰一个类的所有功能而不用为每个方法一遍又一遍地键入它? [英] How to decorate all functions of a class without typing it over and over for each method?

查看:63
本文介绍了如何修饰一个类的所有功能而不用为每个方法一遍又一遍地键入它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说我的课程有很多方法,我想在每个方法上应用我的装饰器,稍后当我添加新方法时,我想应用相同的装饰器,但是我不想在上方写@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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆