python中@的用法
@是一个装饰器,针对函数,起调用传参的作用。
有修饰和被修饰的区别,‘@function’作为一个装饰器,用来修饰紧跟着的函数(可以是另一个装饰器,也可以是函数定义)。
文章目录
代码1:修饰函数
def funA(desA):
print("It's funA")
print('---')
print(desA)
desA()
print('---')
@funA
def funC():
print("It's funC")
结果1
It's funA
---------
<function funC at 0x7f9667abadc0>
It's funC
---------
分析1
@funA修饰函数定义funC,传址funC给funA,为了更直观地看参数传递,打印desA,其传的是funC的地址。
执行的时候由上而下,先定义funA,然后运行funA(funC),输出‘It’s funA’。
执行desA()即调用funC,执行funC()。
值得注意的是
直接修饰和执行funA(funC)的区别
代码1和直接执行funA(funC)的结果有些出入。
> 代码1
>
It's funA
---------
<function funC at 0x7f9667abadc0>
It's funC
---------
> funA(funC)
>
It's funA
---------
None
Traceback (most recent call last):
File "main.py", line 16, in <module>
funA(funC)
File "main.py", line 8, in funA
desA()
TypeError: 'NoneType' object is not callable
- 为什么
print(desA)是None? - 为什么
desA()报错TypeError: 'NoneType' object is not callable?
同一个原因:修饰器函数funA里没有定义返回值。修饰器@funA接收函数funC作为参数,在修饰器函数funA中可以修改参数函数funC,当我们调用被修饰的函数funC时,实际上是在执行被修改过的修饰器函数,但在funA中我们没有返回可调用的函数,默认返回的是None,所以会出现这两个问题,在funA中加上返回值(被修饰后的参数)就可以解决。
def funA(desA):
print("It's funA")
print('---')
print(desA)
desA()
print('---')
return desA # <-- missing return statement before
@funA
def funC():
print("It's funC")
funA(funC)和funA(funC())差别
funA(funC)和funA(funC())是不同的,之前一个笔误将这里的函数调用写成后者。如果我们要执行funA(funC()),也会报错。
> funA(funC)
>
It's funA
---------
<function funC at 0x7fe2a4f04dc0>
It's funC
---------
> funA(funC())
>
It's funC
It's funA
---------
None
Traceback (most recent call last):
File "main.py", line 17, in <module>
funA(funC())
File "main.py", line 8, in funA
desA()
TypeError: 'NoneType' object is not callable
- 为什么多打印了
It's funC? - 为什么
print(desA)是None? - 为什么
desA()报错TypeError: 'NoneType' object is not callable?
这个执行顺序由内向外,先调用funC(),打印了这一句,然后将调用结果返回传给funA,在这里传的并不是函数地址,而是函数结果,是一个None,如果想要不报错,需要在funC返回一个可调用的函数,这与代码1完全不一样。
代码2:修饰装饰器
def funA(desA):
print("It's funA")
return desA
def funB(desB):
print("It's funB")
return desB
@funB
@funA
def funC():
print("It's funC")
结果2
It's funA
It's funB
分析2
@funB 修饰装饰器@funA,@funA 修饰函数定义def funC(),将funC传给funA,再将funA(funC)传给funB。
执行的时候由上而下,先定义funA、funB,然后运行funB(funA(funC))。
此时desA=funC(),然后funA()输出‘It’s funA’;desB=funA(funC),然后funB()输出‘It’s funB’。
3733

被折叠的 条评论
为什么被折叠?



