Why is it necessary to put self as a parameter for method decorators?

For module level functions, this code contains:

def dec(f):
    def wrap(*args, **kwargs):
        f(*args, **kwargs)
    return wrap

@dec
def foo(arg1):
    pass

When decorating, however, all of a sudden you will have to have one parameter to catch the instance.

def dec(f):
    def wrap(self, *args, **kwargs):
        f(self, *args, **kwargs)
    return wrap


class Test:
    def __init__(self):
        pass

    @dec
    def foo(self, arg1):
        pass

Why is this so? What is so special about selfthat *argsyou can't catch him? In the end, is this not one more positional argument? Also, how is this ( self) passed to the inner function wrap?

In the first case, this is simply equivalent foo = dec(foo). From what I learned with closing, before being foopassed as an argument to the decorator. It creates a wrapper with __closure__, so it can save any arguments passed to foo.

, , , self __closure__?

+4
2

? self, *args ?

, . *args self, , . .

:

class Test(object):

  def foo(self, *args):
    return (self,) + args

  def bar(*args):  # for the purposes of illustration
    return args

t = Test()
print(t.foo(42))
print(t.bar(42))

:

def dec(f):
    def wrap(*args, **kwargs):
        return f(*args, **kwargs)
    return wrap

class Test(object):

    @dec
    def foo(self, arg1):
        return (self, arg1)

t = Test()
print(t.foo(42))
+3

Source: https://habr.com/ru/post/1683256/


All Articles