是否有可能在Python中使用实例中的方法在类中装饰方法

时间:2012-11-14 00:57:05

标签: python decorator

我正在尝试在定义类时包装函数,在此类的实例中使用方法

以下是可行的代码

class A(object):   
    def __init__(self):    
        pass       

    @self_decorator 
    def to_be_decorated(self):
        pass       

def self_decorator(fn):    
    from functools import wraps
    @wraps(fn)     
    def wrapper(*args, **kwargs):
        self = args[0]     
        return self.app.route('/twip')(fn(*args, **kwargs))

    return wrapper

我实际上想要得到的东西:

class A(object):   
    def __init__(self):    
        self.app = APP()    

    @self.app.wrapper_function # which apparently doesn't work
    def to_be_decorated(self):
        pass

那么,我的装饰方式是否可行?

2 个答案:

答案 0 :(得分:2)

在类定义中没有自我,因为该类尚不存在且无法实例化。

您可以使用

class A(object):
    app = APP()

    @app.wrapper_function
    def to_be_decorated(self):
        pass

但那将是一个类变量。

答案 1 :(得分:0)

装饰器只是在定义时被调用的函数。

当你这样写:

@self.app.wrapper_function # which apparently doesn't work
def to_be_decorated(self):
    pass

与写这个大致相同:

def to_be_decorated(self):
    pass
to_be_decorated = self.app.wrapper_function(to_be_decorated)

一旦你看到这种方式,很明显为什么这不起作用,并且无法工作。

首先,A的类定义没有自变量,A也没有可以被访问的成员app,即使它已经被访问。相反,A的每个实例都有自己唯一的self.app

即使你希望口译员可以“做我的意思”,如果你考虑一下,这并不意味着什么。你想调用“{”1 {{}}方法,但没有这样的东西。除非您仔细阅读所有相关代码,否则可以定义或重新定义方法,但绝对不能保证来自self.app.wrapper_function的不同实例的self.app.wrapper_function甚至具有相同的基础A。但是,即使他们这样做了,func_code也是一个绑定方法 - 一个方法与它所调用的对象绑定在一起 - 所以它们仍然彼此不同。

有很多方法可以解决这个问题,但它们都是同一个技巧:使用某种间接方式来获取不属于self.app.wrapper_functionself.app成员的函数,并在通话时参考self。这基本上就是你self.app所做的,而这是不可避免的。