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
Advertisement
Answer
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
.