4
class Something:
    def __init__(self, ...):
       ...

    def update(self):
       ...

    def add_update(self, func):
      def fct(*args, **kwargs):
          self.update()
          func(*args, **kwargs)
      return fct 

    @add_update
    def method(self, some_parameter):
       ...

So basically I have this class, and I want to call the function "update()" automatically before I call a method from the class. But I get this error:

TypeError: add_update() missing 1 required positional argument: 'func'

I don't really understand what's wrong here, also I saw some tutorials on the internet where they did something similar and it was working. Can someone explain me what's wrong here and how do I fix it?

3 Answers3

3

What is a decorator? It's syntactic sugar for more verbose syntax.

@decorator
def my_fun():
   ...

is the same as

my_fun = decorator(my_fun)

So in your specific case

method = add_update(method)

Do you see a problem? Add update expects two parameters (self, and func), but here it gets only one (and actually you pass method as self).

To solve this you need to create decorator outside the class that gets only function, and that functions first parameter will be self:

def add_update(func):
     def wrapper(*args):
         self = args[0]
         ...
AsukaMinato
  • 1,017
  • 12
  • 21
kosciej16
  • 6,294
  • 1
  • 18
  • 29
0

when you use @add_update, It is equivalent to add_update(method), At this time add_update is still a function.

You can make the following modifications to make it work

class Something:
    def __init__(self):
        ...

    def update(self):
        ...

    def add_update(f):
        def fct(self, *args, **kwargs):
            self.update()
            return f(self, *args, **kwargs)

        return fct

    @add_update
    def method(self, some_parameter):
        ...

mxp-xc
  • 456
  • 2
  • 6
  • Now when I call the "method" method from the class. I get the following error: method() missing 1 required positional argument: 'some_parameter' –  Dec 20 '21 at 14:40
  • `method` it is a method, it has parameters, you need to add parameters to it, such as `Something().method(1)` – mxp-xc Dec 20 '21 at 14:43
  • You may be using the above example instead of mine, where `Something.update()` is called instead of `args[0].update()`, so it will cause an error – mxp-xc Dec 20 '21 at 14:45
  • I am using your example, and I did something like this: test = Something(...) test.method(some_parameter) And I get this error: method() missing 1 required positional argument: 'some_parameter' –  Dec 20 '21 at 14:47
  • I run here and will not report an error, can you post a screenshot of your code – mxp-xc Dec 20 '21 at 14:51
  • this is my code https://onlinegdb.com/Zj0MjcpZu – mxp-xc Dec 20 '21 at 15:01
0

You have to pass the argument func and define the class inside the decorator function.

class Something:
    def __init__(self,..):
        ...
      

    def update(self):
       ...

    def add_update( func):
      def fct(*args, **kwargs):
          args[0].update() #or Something.update()
          func(*args, **kwargs)
      return fct 

    @add_update
    def method(self, some_parameter):
        ...
I_Al-thamary
  • 3,385
  • 2
  • 24
  • 37