Home > Software engineering >  "parameter 'self' unfilled" when using decorators, even after instantiating obje
"parameter 'self' unfilled" when using decorators, even after instantiating obje

Time:09-28

I'm using a decorator with parameters to do something with an instance attribute (self.x in this example, if track_bool is true). However when running I get the "parameter 'self' unfilled" error when calling b.do(). From what I understand this error is supposed to appear when calling an instance method before instantiating an object, so I don't understand why it appears in this case when I've used b=B(). Is this something to do with the fact I'm using decorators ? Help please !

Edit: The code does run, but I would like to understand the error so that it doesn't risk breaking anything when running with the rest of my code.

# make decorator
def incrementor(track_bool):
    def wrapper(f):
        def wrapped_f(self, *args, **kwargs):
            if track_bool:
                self.x  = 1  # do something with self.x
                print('increment')
            return f(self, *args, **kwargs)
        return wrapped_f
    return wrapper


class B:
    def __init__(self):
        self.x = 0

    @incrementor(track_bool=True)
    def do(self):
        print("this is a function with x=", self.x)


b = B()  # instantiate
b.do()  # call decorated method

Here is the image of the error: PyCharm IDE message

CodePudding user response:

Ok, this is PyCharm being a tiny bit too eager. You should submit a bug report for this because your code is actually working just fine and you don't want to have to go round suppressing all calls to decorated methods.

Here is a work-around. You can change the decorator to not have an explicit self parameter:

def incrementor(track_bool):
    def wrapper(f):
        def wrapped_f(*args, **kwargs):
            if track_bool:
                self = args[0]
                self.x  = 1  # do something with self.x
                print('increment')
            return f(*args, **kwargs)
        return wrapped_f
    return wrapper

Note how you can still get hold of self because it is guaranteed to be the first element of args.

  • Related