用参数包装装饰器
Wrapping a decorator, with arguments
我正在尝试用一个在调用 marshal_with
之前执行某些操作的装饰器替换 flask-restful
中的 marshal_with
装饰器。我的方法是尝试实现一个包装 marshal_with
.
的新装饰器
我的代码如下:
from flask.ext.restful import marshal_with as restful_marshal_with
def marshal_with(fields, envelope=None):
def wrapper(f):
print("Do something with fields and envelope")
@wraps(f)
def inner(*args, **kwargs):
restful_marshal_with(f(*args, **kwargs))
return inner
return wrapper
不幸的是,这似乎破坏了一切......没有错误消息,但我的 API returns 一个不应该的空响应。关于我做错了什么的任何见解?
我不知道marshal_with
的细节,但完全可以在一个函数上使用多个装饰器。例如:
def decorator_one(func):
def inner(*args, **kwargs):
print("I'm decorator one")
func(*args, **kwargs)
return inner
def decorator_two(text):
def wrapper(func):
def inner(*args, **kwargs):
print(text)
func(*args, **kwargs)
return inner
return wrapper
@decorator_one
@decorator_two("I'm decorator two")
def some_function(a, b):
print(a, b, a+b)
some_function(4, 7)
给出的输出是:
I'm decorator one
I'm decorator two
4 7 11
您可以通过在每个 inner
函数调用后添加打印语句来修改这个小脚本,以查看每个装饰器之间的确切流程控制。
我在这里做错了几件事,首先,未能如 jonrsharpe 指出的那样 return restful_marshal_with
的输出,其次,未能理解编写为class 而不是函数,以及如何正确地将值传递给它。正确的代码最终是:
def marshal_with(fields, envelope=None):
def wrapper(f):
print("Do something with fields and envelope")
@wraps(f)
def inner(*args, **kwargs):
rmw = restful_marshal_with(fields, envelope)
return rmw(f)(*args, **kwargs)
return inner
return wrapper
如您所见,除了不 returning rmw()
之外,我还需要在调用它之前正确初始化 request_marshal_with
class。最后,重要的是要记住装饰器 return 函数,因此原始函数的参数应该传递给 rmw(f)
的 return 值,因此语句 return rmw(f)(*args, **kwargs)
。如果您看一下 flask_restful.marshal_with
代码 here.
,这可能会更明显
我正在尝试用一个在调用 marshal_with
之前执行某些操作的装饰器替换 flask-restful
中的 marshal_with
装饰器。我的方法是尝试实现一个包装 marshal_with
.
我的代码如下:
from flask.ext.restful import marshal_with as restful_marshal_with
def marshal_with(fields, envelope=None):
def wrapper(f):
print("Do something with fields and envelope")
@wraps(f)
def inner(*args, **kwargs):
restful_marshal_with(f(*args, **kwargs))
return inner
return wrapper
不幸的是,这似乎破坏了一切......没有错误消息,但我的 API returns 一个不应该的空响应。关于我做错了什么的任何见解?
我不知道marshal_with
的细节,但完全可以在一个函数上使用多个装饰器。例如:
def decorator_one(func):
def inner(*args, **kwargs):
print("I'm decorator one")
func(*args, **kwargs)
return inner
def decorator_two(text):
def wrapper(func):
def inner(*args, **kwargs):
print(text)
func(*args, **kwargs)
return inner
return wrapper
@decorator_one
@decorator_two("I'm decorator two")
def some_function(a, b):
print(a, b, a+b)
some_function(4, 7)
给出的输出是:
I'm decorator one
I'm decorator two
4 7 11
您可以通过在每个 inner
函数调用后添加打印语句来修改这个小脚本,以查看每个装饰器之间的确切流程控制。
我在这里做错了几件事,首先,未能如 jonrsharpe 指出的那样 return restful_marshal_with
的输出,其次,未能理解编写为class 而不是函数,以及如何正确地将值传递给它。正确的代码最终是:
def marshal_with(fields, envelope=None):
def wrapper(f):
print("Do something with fields and envelope")
@wraps(f)
def inner(*args, **kwargs):
rmw = restful_marshal_with(fields, envelope)
return rmw(f)(*args, **kwargs)
return inner
return wrapper
如您所见,除了不 returning rmw()
之外,我还需要在调用它之前正确初始化 request_marshal_with
class。最后,重要的是要记住装饰器 return 函数,因此原始函数的参数应该传递给 rmw(f)
的 return 值,因此语句 return rmw(f)(*args, **kwargs)
。如果您看一下 flask_restful.marshal_with
代码 here.