Self-referencing inside class definition

喜欢而已 提交于 2019-12-04 03:26:19

问题


How do I reference class object inside class definition? Could you advice me how you would do it? Or more specifically how do you pass class object inside decorator of class method? Here is a simple example, I'm trying to pass second method I'm declaring to decorator of first one.

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 

As expected exception is raised

NameError: name 'A' is not defined

As a result of my investigation i learned that globals() doesn't contain A key while i'm inside decorate or _wrap functions, but defined inside _call. So I could probably find passed method by string name (e.g @dec('A.w')), but in that case it is impossible to cache method search inside _wrap closure.

So how do you fix that? :)


回答1:


You cannot, because during class definition, the class does not yet exist.

You can apply the decorator after the class has been created:

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

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

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

or you can swap the order of the two method definitions and refer to w as a local name still:

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

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

In both cases you are passing in a callable A.w that is not bound to an instance. No self will be passed in, so you need to add that yourself, in the decorator:

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

If you didn't expect w to be bound (it acting as a static method instead), you could just use a normal function instead here.

Generally speaking, creating a decorator to call another method on the same instance is somewhat pointless; why not just call w from within f, directly?

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

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


来源:https://stackoverflow.com/questions/20035153/self-referencing-inside-class-definition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!