var = float(input('Enter a number: '))
def math_test(func):
def wrapper(*args, **kwargs):
func(var)
return wrapper
@math_test
def times10(x):
print(x * 10)
times10()
Why is it that when I call the function times10(), that I don't need to put the argument var in the brackets?
When I didn't type the argument var when I called func() I got an error saying requiring positional argument x...so when I put var in times10() I got the same error.
However when I placed the argument in func() it worked fine.
Shouldn't the wrapper function know that the argument in times10(), which would be var, should also be the argument in func()?
Edit:
var = float(input('Enter a number: '))
def math_test(func):
def wrapper(*args, **kwargs):
func(*args, **kwargs)
return wrapper
@math_test
def times10(x):
print(x * 10)
times10(var)
CodePudding user response:
This decorated function:
@math_test
def times10(x):
print(x * 10)
Will be translated to:
times10 = math_test(times10)
Which means times10 is now equivalent to:
def wrapper(*args, **kwargs):
func(var)
Where the callable func points to the original implementation of times10. To further visualize this, think of it as like this:
def times10(*args, **kwargs):
def original_times10(x):
print(x * 10)
original_times10(var)
- If you call
func(var)which is synonymous above tooriginal_times10(var)then it would work sinceoriginal_times10is passedvarwhich would be put the argumentx. - If you call
func()which is synonymous above tooriginal_times10(), it will obviously not work becauseoriginal_times10requires an inputxbut yet you didn't pass it anything.
Note that what you are trying to do is strictly passing a fixed argument var to the original implementation of times10:
func(var)
Depending on your usecase, I believe what you should be doing is passing the actual arguments:
func(*args, **kwargs)
This way, whatever you pass to the decorated function of times10 would be passed to the original implementation of times10.
