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_times10
is passedvar
which would be put the argumentx
. - If you call
func()
which is synonymous above tooriginal_times10()
, it will obviously not work becauseoriginal_times10
requires an inputx
but 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
.