0

For understanding decorators in Python, i created in a class an example. But when i run it i receive an error.

class Operation:

    def __init__(self, groupe):
        self.__groupe = groupe

    @property
    def groupe(self):
        return self.__groupe

    @groupe.setter
    def groupe(self, value):
        self.__groupe = value

    def addition(self, func_goodbye):
        ln_house = len('house')
        ln_school = len('school')
        add = ln_house + ln_school
        print('The result is :' + str(add))
        return func_goodbye

    @addition
    def goodbye(self):
        print('Goodbye people !!')


if __name__ == '__main__':
    p1 = Operation('Student')
    p1.goodbye()

I receive this error :

Traceback (most recent call last): File "Operation.py", line 1, in class Operation: File "Operation.py", line 21, in Operation @addition TypeError: addition() missing 1 required positional argument: 'func_goodbye'

7
  • addition(self, func_goodbye) requires the parameter func_goodbye which is no given. Commented Apr 9, 2020 at 22:28
  • Moreover, why are you calling your decorator method directly? Shouldn't you be calling goodbye? Commented Apr 9, 2020 at 22:30
  • Side note: using properties in this way is an bad practice in Python. Properties are meant for implementing functionality without breaking attribute access. They have no benefit as trivial "getters" and "settters". Likewise, there is no reason to use double-underscored names here. Double-underscored names are for name mangling with inheritance, not for hiding attributes. Commented Apr 9, 2020 at 22:30
  • As an aside, your groupe property is completely pointless and defeat the entire purpose of property. Just delete them and use a normal, groupe attribute. Commented Apr 9, 2020 at 22:33
  • It seems to me that we cannot have our own decorator in a class !!! Is it true ? Commented Apr 9, 2020 at 22:45

1 Answer 1

4

You can have a class scoped decorator, however there won't be a self when the decorator is called

a decorator:

@foo
def bar(): ...

is roughly equivalent to

def bar(): ...
bar = foo(bar)

in your particular example, if you remove the self parameter, it should function as you expect:

    def addition(func_goodbye):
        ln_house = len('house')
        ln_school = len('school')
        add = ln_house + ln_school
        print('The result is :' + str(add))
        return func_goodbye

    @addition
    def goodbye(self):
        print('Goodbye people !!')

for good measure, I might del addition after that just to ensure it isn't accidentally called later

(an aside: one unfortunate side-effect of this is many linters and type checkers will consider this "odd" so I've yet to find a way to appease them (for example mypy))

Sign up to request clarification or add additional context in comments.

9 Comments

The way to appease them is to not put things in the class scope that shouldn't be there. You could also use the @staticmethod decorator, but really, this decorator should just be in the module-level scope. Upvoted, though.
@juanpa.arrivillaga do you have anything to back your opinions? it might make sense (for example) from a design perspective to have a private decorator that knows things about the class internals -- you'd have an equivalent linter problem as you try and modify those internals and (at least to me) a decorator defined in the class body makes a lot of sense in that case
Perhaps a @classmethod in that case, however, in this case, the function explicitly doesn't use any internal state, so it shouldn't be part of the class.
@juanpa.arrivillaga easily, here's an example
@classmethod doesn't help for this, there's no class at the time you'd want to run the decorator (NameError: <classname> is not defined), and @staticmethod doesn't work either as it makes a descriptor (staticmethod is not callable)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.