Почему python Flask декоратор не залогинен? - PullRequest
1 голос
/ 11 апреля 2020

У меня есть простое приложение Flask, где я хочу проверять запросы в формате json с помощью декоратора, например:

def validate_request(*expected_args):
    """
    Validate requests decorator
    """
    # print('=======================ENTER VALIDATE_REQUEST================')
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            json_obj = request.get_json()
            for expected_arg in expected_args:
                if expected_arg not in json_obj or json_obj.get(expected_arg) is None:
                    return api_response({'error': f"You must call with all request params: {', '.join(expected_args)}"})
            return func(*args, **kwargs)
        return wrapper
    return decorator

И на стороне маршрута, например:

@user_api.route('/login', methods=['POST'])
@validate_request('email', 'password')
def login():
    req_data = request.get_json()
......................

У меня вопрос, почему оператор PRINT от декоратора не отображается, когда я вызываю маршрут '/ login'?

Сообщение регистрируется только при запуске сервера (flask run).

Спасибо.

Ответы [ 2 ]

1 голос
/ 11 апреля 2020

Ваше печатное заявление в validate_request. Хотя validate_request возвращает декоратор, сам по себе он не является декоратором. Это фабрика декораторов , если хотите, и выполняется только один раз, чтобы создать декоратор и декорировать login, когда python загружает ваш код, поэтому ваш оператор печати выполняется только один раз при загрузке ваш сервер. Имейте в виду, что сам декоратор также выполняется только один раз, чтобы заменить login тем, что возвращает декоратор, в данном случае wrapper. Итак, wrapper - это действительная функция, которая будет вызываться при каждом запросе. Если вы разместите там свое заявление на печать, вы увидите его при каждом запросе.

def validate_request(*expected_args):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print("=== Enter validate request ===")
            return func(*args, **kwargs)
        return wrapper
    return decorator
1 голос
/ 11 апреля 2020
Декораторы

Python заменяют функции, которые они декорируют. Эта замена происходит в начале программы, когда интерпретатор читает код. Это когда ваш оператор печати будет выполнен. По истечении этого времени возвращаемая функция будет единственным кодом, который будет запущен. Если вы хотите, чтобы печать выполнялась при каждом вызове, вам нужно ввести фактическую функцию, которая будет вызываться:

def validate_request(*expected_args):
    """
    Validate requests decorator
    """
    # print('=======================Function Decoration Happening================')
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print("==== ENTER VALIDATE_REQUEST ===")
            json_obj = request.get_json()
            for expected_arg in expected_args:
                if expected_arg not in json_obj or json_obj.get(expected_arg) is None:
                    return api_response({'error': f"You must call with all request params: {', '.join(expected_args)}"})
            return func(*args, **kwargs)
        return wrapper
    return decorator
...