python - 为什么这个装饰器中的包装函数会自动运行而不调用它们?
问题描述
我正在探索如何在 python 3 中使用装饰器。我在编辑器中输入了这些代码并单击了“运行”按钮。
log_stat = False
def decorator():
def wrapper(func):
global log_stat
while not log_stat:
username = input("username")
password = input("password")
if username == "123" and password == "456":
func()
log_stat = True
else:
print("try again")
return wrapper
@decorator()
def welcome():
print("welcome")
我不希望屏幕上显示任何内容,因为我认为我所做的只是定义函数而不是调用或执行它们。但是python让我输入用户名和密码,看起来它实际上已经运行了包装函数。
这样做的真正原因是什么?我怎样才能在不触发包装的情况下定义函数?
解决方案
装饰器是一个可调用的,它接受一个类或函数并返回一个类或函数。装饰器语法是
@decorator # note no ()
def function():
...
您正在做的是调用decorator
,然后使用该调用 ( wrapper
) 的结果来装饰welcome
. wrapper
因此立即运行。
你打算写的可能是
def decorator(func):
def wrapper(*args, **kwargs):
global log_stat
while not log_stat:
username = input("username")
password = input("password")
if username == "123" and password == "456":
log_stat = True
return func(*args, **kwargs)
else:
print("try again") # I would raise an exception here
return wrapper
@decorator
def welcome():
print("welcome")
请注意,wrapper
在此版本中需要参数。这是因为当你装饰时welcome
,它会被替换为wrapper
. 因此,如果您的welcome
函数接受参数,您wrapper
还必须接受它们才能将它们传递给原始函数。
推荐阅读
- macos - 检测是否安装并启用了 Safari 应用程序扩展
- python - AttributeError:“命名空间”对象没有属性“url”
- python - 当我尝试在 python 中使用 xlrd 比较两张工作表时,代码没有运行
- jquery - jQuery .val() 连接而不是加法
- postgresql - 如何通过引用表A为表B添加外键,通过引用表B在PostgreSQL中为表A添加外键?
- google-chrome - Karma:使用来自 WSL 的 Windows 的 Chrome
- c# - SqlDataReader 因未知原因关闭
- ibm-datapower - 在 API Connect 中为特定字段添加分析
- wso2 - 如何在芭蕾舞演员中使用 jsonpath?
- ionic-framework - 如何在角度项目中使用离子脚本