vendredi 9 mars 2018

Python decorators method vs. class behaviour [duplicate]

This question already has an answer here:

trying to develop a lazy initialisation decorator in python I stumbled across some odd behaviour.

Please consider the following code:

def initialiserMethod(function):
    print("initialiserMethod()")

    def wrapper(*args, **kwargs):
        print("wrapper()")
        print(args)
        function(*args, **kwargs)
    return wrapper


class InitialiserClazz(object):

    def __init__(self, f):
        print("InitialiserClazz.__init__()")
        self.f = f

    def __call__(self, *args, **kwargs):
        print("InitialiserClazz.__call__()")
        print(args)
        self.f(*args)


class Decorated(object):

    @initialiserMethod
    def methInit(self, msg):
        print(msg)

    @InitialiserClazz
    def classInit(self, msg):
        print(msg)


if __name__ == '__main__':
    print('===================================\n')
    obj = Decorated()

    obj.methInit('test')
    print('\n')
    obj.classInit('test')

Loading it with python3 test.py yields the following output:

initialiserMethod()
InitialiserClazz.__init__()
===================================

wrapper()
(<__main__.Decorated object at 0x7f98d8bc6080>, 'test')
test

InitialiserClazz.__call__()
('test',)
Traceback (most recent call last):
  File "test.py", line 46, in <module>
    obj.classInit('test')
  File "test.py", line 27, in __call__
    self.f(*args)
TypeError: classInit() missing 1 required positional argument: 'msg'

It seems that the self from the Decorated class is not passed to the __call__ arguments in InitialiserClazz. Can anyone explain why this is happening?

Aucun commentaire:

Enregistrer un commentaire