This article is [python] Movement of decorator that can be understood this time ① Decorator that does not receive arguments is a continuation.
The goal of this article is to understand the following forms of decorators:
def deco(a):
#processing
@deco(a="hello")
def test():
#processing
Let's check the behavior of the decorator ** that receives ** arguments with a minimum of code.
def foo(b):
pass
def deco(a):
print(a)
return foo
@deco(a="hello")
def test():
pass
#Execution result
# hello
Let's look at each line. Lines 1-6 just define the function, so nothing happens.
When the 8th line @ deco (a =" hello ")
is reached, deco (a =" hello ")
is executed first.
Lines 4-6 The function deco
is executed, and when" hello "is passed to a, the character string hello
is output.
And it returns the function foo
.
The inside of my head is like ↓.
Because deco (a =" hello ")
of @ deco (a =" hello ")
is executed and the function foo
is returned,
deco (a =" hello ")
has been replaced with foo
, and the 8th line is now @ foo
.
To summarize so far,
When the code reaches @deco (argument)
, deco (argument)
is executed first
From this point onward, [python] movement of the decorator that can be understood this time ① Decorator that does not receive arguments ** Exactly the same as steps 1 to 3 **. So I'll take a quick look after that. Please read ↑ for detailed movements.
def foo(func):
print(func.__name__)
return func
def deco(a):
print(a)
return foo
@deco(a="hello")
def test():
print("inside test func")
pass
test()
#output
# hello
# test
On line 8, deco (a =" hello ")
is executed as in step 1, and the function foo
is returned after hello
is output.
At this point replace @ deco (a =" hello ")
with @ foo
in your head.
foo
is a function that outputs the \ _ \ _ name \ _ \ _ attribute of func
and returns func
.
If you replace @ deco (a =" hello ")
with @ foo
in your head, you will find the function foo
after @
.
The function on the line following @
is passed as the first argument of the function after @
(in this case foo
).
Therefore, in terms of image,
deco (a =" hello ")
is executed at the time of @ deco (a =" hello ")
.deco (a =" hello ")
is executed, hello
is output and the function foo
is returned.@ deco (a =" hello ")
can be considered as @ foo
.test
immediately after @ foo
is definedtest
is passed as an argument to the function foo
and foo
is executed.foo
(= function test
) is assigned to the variable test
.inside test func
is output.It feels like.
The point is that ** the function deco
must return a function (callable) **.
This is because an error occurs because it cannot be called without returning a function.
Example) If the return statement of the deco function is set to return 123
, an error will occur when trying to call the int
type 123 like 123 (test)
at number 5 in the above image.
def deco(a):
print(a)
return 123
@deco(a="hello")
def test():
print("inside test func")
pass
#result
# hello
# Traceback (most recent call last):
# File "test.py", line 5, in <module>
# @deco(a="hello")
# TypeError: 'int' object is not callable
The image is as follows.
deco (a =" hello ")
is executed and 123
is returned@ deco (a =" hello ")
to @ 123
in your headtest
is defined because there isdef test ():
immediately after @ 123
.123 (test)
is executed and 'int' object is not callable
is output. This is because 123
is not a function and cannot be called.def foo(func):
print(func.__name__)
return "aaa"
def deco(a):
print(a)
return foo
@deco(a="hello")
def test():
print("inside test func")
pass
test()
#result
# hello
# test
# Traceback (most recent call last):
# File "test.py", line 17, in <module>
# test()
# TypeError: 'str' object is not callable
The image looks like the following.
deco (a =" hello ")
is executed and the function foo
is returned@ deco (a =" hello ")
with @ foo
in your headtest
is defined after @ foo
test
is passed to function foo
foo
returns the string"aaa"
" aaa "
is stored in the variable test
test ()
is doing"aaa" ()
,'str' object is not callable
is output. This error occurs because " aaa "
is not a function.If you are not sure, it is recommended to experiment with it because it will be easier to understand the movement.
Recommended Posts