为什么 python Flask 装饰器没有记录?
Why python Flask decorator not logged?
我有一个简单的 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()
......................
我的问题是为什么当我调用 '/login' 路由时装饰器的 PRINT 语句没有显示?
仅当我启动服务器(flask 运行)时才会记录该消息。
谢谢。
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
您的打印语句在 validate_request
中。 validate_request
returns虽然是装饰器,但它本身并不是装饰器。如果你愿意,它是一个 装饰器工厂 ,并且只执行一次以创建装饰器并在 python 加载你的代码时装饰 login
,因此为什么你的 print 语句仅在启动服务器时执行一次。请记住,装饰器本身也只执行一次以将 login
替换为任何装饰器 returns,在本例中为 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
我有一个简单的 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()
......................
我的问题是为什么当我调用 '/login' 路由时装饰器的 PRINT 语句没有显示?
仅当我启动服务器(flask 运行)时才会记录该消息。
谢谢。
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
您的打印语句在 validate_request
中。 validate_request
returns虽然是装饰器,但它本身并不是装饰器。如果你愿意,它是一个 装饰器工厂 ,并且只执行一次以创建装饰器并在 python 加载你的代码时装饰 login
,因此为什么你的 print 语句仅在启动服务器时执行一次。请记住,装饰器本身也只执行一次以将 login
替换为任何装饰器 returns,在本例中为 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