关于一个装饰器的问题请教

2020-06-23 10:52:26 +08:00
 saximi
from functools import wraps
def decorator_name(f):
@wraps(f)
def decorated(*args,**kwargs):
if not can_run:
return "FUNCTION WILL NOT RUN" #装饰器中第一个 return
return f(*args,**kwargs) #装饰器中第二个 return
return decorated #装饰器中第三个 return

@decorator_name
def func():
return("FUNCTION IS RUNNING")

can_run=True
print(func())

上面是我从某个材料中看到的装饰器的代码,运行后会输出“FUNCTION IS RUNNING”。
我不理解的地方在于我标注出的装饰器中的三个 return 语句:
当 can_run 是 False 时,会执行第一个 return ;
否则当 can_run 是 True 时,会执行第二个 return 。
上面两种情况已经涵盖了所有的情形了,那么第三个 return 岂不是永远不会被执行到?
所以我感觉上面的代码写法是不合适的,应该把多余的第三个 return 语句去掉? 但是感觉去掉第三个语句,又不是装饰器的规范写法了。
百思不得其解,恳请大家指点,感谢!
2339 次点击
所在节点    Python
7 条回复
runze
2020-06-23 11:11:15 +08:00
第三个 return 不在 decorated 函数内,跟 if 没关系,返回 decorated 函数
12tall
2020-06-23 11:12:46 +08:00
对于 python 这种没有花括号的语言,也许你改下排版就能看出来了,第三个 return 返回的是一个函数
![py]( https://s1.ax1x.com/2020/06/23/NtIGVJ.png)
xiaolinjia
2020-06-23 11:12:54 +08:00
第三个 return 是必须的。返回的是装饰器内部的 decorated 函数的引用。换句话说,被装饰器装饰的 func 函数,其引用已经变成了 decorated 函数。即 func = decorator_name(func)。
不信你可以 print(func.__name__)。看看是不是 decorated 。
xulolololololo
2020-06-23 11:26:36 +08:00
没有缩进看不懂,楼下帮楼主解答一下
no1xsyzy
2020-06-23 14:21:00 +08:00
@12tall #2 L6-L10 少缩进一层
12tall
2020-06-23 16:41:17 +08:00
@no1xsyzy 哈哈 多谢
fasionchan
2020-06-24 09:46:26 +08:00
你需要理解装饰器语法糖 @的运行原理,我写过一篇文章,应该可以说清楚: https://python.fasionchan.com/zh_CN/latest/practices/advanced-decorator.html

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/684015

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX