почему обернутая функция в этом декораторе запускается автоматически, и ни один из них не вызывается? - PullRequest
0 голосов
/ 29 января 2019

Я изучаю, как использовать decorator в 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 попросил меня ввести имя пользователя и пароль, которые, похоже, действительно запустили упакованную функцию.

Какова реальная причина этого?И как я могу просто определить функцию, не вызывая упакованную?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Декоратор - это вызываемый объект, который принимает класс или функцию и возвращает класс или функцию.Синтаксис декоратора:

@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 также должна будет принимать их, чтобы передать их исходной функции.

0 голосов
/ 29 января 2019

Потому что вы вызвали декоратор при его использовании.Это означает, что он работает во время импорта.Вы должны удалить круглые скобки.

@decorator
def welcome():                 
    print("welcome")

(Можно определить декоратор, который вызывается во время импорта, если он принимает параметры; но для этого необходимо реализовать другой уровень переноса, поэтомучто функция возвращает декоратор, который, в свою очередь, возвращает функцию, которая упаковывает оригинал.)

...