[英]Python - Unable to set multiple attributes from utilizing multiple decorators
I am utilizing multiple decorators on a flask API route and I am setting attributes within those decorators (functools wraps), however I am only able to set attributes from within the first decorator that is being called.我在 flask API 路由上使用了多个装饰器,并且我在这些装饰器(functools wraps)中设置属性,但是我只能从被调用的第一个装饰器中设置属性。 I would like to have the ability to set and reference attributes from all decorators being called.我希望能够设置和引用所有被调用的装饰器的属性。
decorators.py装饰器.py
from functools import wraps
def example_func1(f):
@wraps(f)
def decorated(*args, **kwargs):
setattr(decorated, 'name', 'bill')
return f(*args, **kwargs)
return decorated
def example_func2(f):
@wraps(f)
def decorated(*args, **kwargs):
setattr(decorated, 'cookie', 'chocolate')
return f(*args, **kwargs)
return decorated
def example_func3(f):
@wraps(f)
def decorated(*args, **kwargs):
setattr(decorated, 'shoes', 'nike')
return f(*args, **kwargs)
return decorated
Flask Route: Flask 路线:
@app.route("/myRoute", methods=["GET", "OPTIONS"])
@example_func1
@example_func2
@example_func3
def my_route():
print(my_route.name) # this returns 'bill' as expected
print(my_route.cookie) # stack trace for no attribute
print(my_route.shoes) # didn't get this far
Error message from stack trace:来自堆栈跟踪的错误消息:
AttributeError: 'function' object has no attribute 'cookie'
You can move the setattr
after the def
, so that you're assigning the attribute on the decorated
function that you just defined (and that you'll be returning), like this:您可以将setattr
移到def
之后,以便在您刚刚定义(并且您将返回)的decorated
function 上分配属性,如下所示:
def example_func3(f):
@wraps(f)
def decorated(*args, **kwargs):
return f(*args, **kwargs)
setattr(decorated, 'shoes', 'nike')
return decorated
I've tested (outside of flask), this works for me.我已经测试过(在烧瓶外),这对我有用。
But of course, this begs the question: why do I need decorated
and @wraps?但是当然,这引出了一个问题:为什么我需要decorated
和@wraps? Well, I'm not sure you do, this also works for me (again, without flask):好吧,我不确定你是否这样做,这也适用于我(同样,没有烧瓶):
from functools import wraps
def example_func1(f):
f.name = 'bill'
return f
def example_func2(f):
f.cookie = 'chocolate'
return f
def example_func3(f):
f.shoes = 'nike'
return f
@example_func1
@example_func2
@example_func3
def func():
print(f'func: name={func.name}')
print(f'func: cookie={func.cookie}')
print(f'func: shoes={func.shoes}')
func()
(Note that I've simplified the setattr
call) (请注意,我已经简化了setattr
调用)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.