在类定义中自引用

时间:2013-11-17 19:33:24

标签: python class decorator python-decorators class-members

如何在类定义中引用类对象?你能告诉我你会怎么做吗?或者更具体地说,如何在类方法的decorator中传递类对象? 这是一个简单的例子,我正在尝试传递第二种方法,我正在宣布第一种方法的装饰。

def decorate(w):
    def _wrap(f):
        def _call(*args, **kwargs):
            return w(f(*args, **kwargs))
        def _call
    return _wrap

class A():

    @dec(A.w)
    def f():
        return 2

    def w(f):
        return fr + 5 

正如预期的那样引发异常

NameError: name 'A' is not defined

根据我的调查,我了解到globals()在我Adecorate函数内部时不包含_wrap键,但在_call内定义1}}。所以我可能会找到按字符串名称传递的方法(例如@dec('A.w')),但在这种情况下,不可能在_wrap闭包内缓存方法搜索。

那你怎么解决这个问题? :)

1 个答案:

答案 0 :(得分:5)

您不能,因为在课程定义期间,该课程尚不存在

您可以在创建类后应用装饰器:

class A():
    def f(self):
        return 2

    def w(self, f):
        return fr + 5 

A.f = dec(A.w)(A.f.__func__)

或者您可以交换两个方法定义的顺序,并将w称为本地名称:

class A():
    def w(self, f):
        return fr + 5 

    @dec(w)
    def f(self):
        return 2

在这两种情况下,您都传入一个绑定到实例的 的可调用A.w。不会传入self,因此您需要在装饰器中自行添加:

def decorate(w):
    def _wrap(f):
        def _call(self, *args, **kwargs):
            return w(self, f(*args, **kwargs))
        def _call
    return _wrap

如果您不希望w 绑定(它充当静态方法),您可以在此处使用普通函数。

一般来说,创建一个装饰器来调用同一个实例上的另一个方法是没有意义的;为什么不直接从w 中调用f

class A():
    def f(self):
        return self.w(2)

    def w(self, f):
        return fr + 5