首页 > 解决方案 > 为什么这个装饰器中的包装函数会自动运行而不调用它们?

问题描述

我正在探索如何在 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让我输入用户名和密码,看起来它实际上已经运行了包装函数。

这样做的真正原因是什么?我怎样才能在不触发包装的情况下定义函数?

标签: pythonpython-3.xfunctionpython-decoratorssyntactic-sugar

解决方案


装饰器是一个可调用的,它接受一个类或函数并返回一个类或函数。装饰器语法是

@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还必须接受它们才能将它们传递给原始函数。


推荐阅读