我正在尝试学习装饰器,并且在为方法设置多个装饰器时克服了一个奇怪的情况。我有两个装饰器@makeupper
和@decorator_maker_with_arguments
。
@decorator_maker_with_arguments
演示了如何在装饰器中访问参数。通过打印提供的args可以很好地完成这项工作,但我看到@makeupper
出现故障。它打印None
。我在它的方法定义旁边放了一个print语句来查看它是否被调用并打印但是从不以hello()大写字母打印字母。
当我发表评论@decorator_maker_with_arguments("swadhikar", "c")
时,我发现@makeupper
效果很好。有人能解释我在这里纠缠不清吗?
def makeupper(some_fun):
def wrapper(arg1, arg2):
return some_fun(arg1, arg2).upper()
return wrapper
def decorator_maker_with_arguments(decorator_arg1, decorator_arg2):
"""Decorator make that demonstrates decorators with arguments"""
print "I am a decorator maker and you passed \"{}:{}\" while calling me...".format(decorator_arg1, decorator_arg2)
def my_decorator(fn):
def wrapper(fn_arg1, fn_arg2):
print "I am the wrapper and I can access the method args \"{}:{}\"".format(fn_arg1, fn_arg2)
return wrapper
return my_decorator
@decorator_maker_with_arguments("swadhikar", "c")
@makeupper
def hello(ar1, ar2):
return "Hello User!"
结果:
I am a decorator maker and you passed "swadhikar:c" while calling me...
I am the wrapper and I can access the method args "hello_arg1:another hello arg..."
None
答案 0 :(得分:1)
但我看到@makeupper发生故障。它会打印
None
makeupper
没有发生故障。外部装饰者decorator_maker_with_arguments
未调用wrapper
的{{1}}。
然后你有一个makeupper
,因为你没有从None
wrapper
返回任何内容。
decorator_maker_with_arguments
的以下修改反映了建议的调整:
decorator_maker
<强>输出强>:
def decorator_maker_with_arguments(decorator_arg1, decorator_arg2):
"""Decorator make that demonstrates decorators with arguments"""
print "I am a decorator maker and you passed \"{}:{}\" while calling me...".format(decorator_arg1, decorator_arg2)
def my_decorator(fn):
def wrapper(fn_arg1, fn_arg2):
out = fn(fn_arg1, fn_arg2)
print "I am the wrapper and I can access the method args \"{}:{}\"".format(fn_arg1, fn_arg2)
return out
return wrapper
return my_decorator
你可以通过用functool.wraps
装饰你的包装来添加一些语法糖,但可以说这是必要的,至少如果你想保留函数名,文档字符串等等。
答案 1 :(得分:1)
您可以在my_decorator包装函数中添加return语句。
如下:
def makeupper(some_fun):
def wrapper(arg1, arg2):
return some_fun(arg1, arg2).upper()
return wrapper
def decorator_maker_with_arguments(decorator_arg1, decorator_arg2):
"""Decorator make that demonstrates decorators with arguments"""
print "I am a decorator maker and you passed \"{}:{}\" while calling me...".format(decorator_arg1, decorator_arg2)
def my_decorator(fn):
def wrapper(fn_arg1, fn_arg2):
print "I am the wrapper and I can access the method args \"{}:{}\"".format(fn_arg1, fn_arg2)
return fn(fn_arg1, fn_arg2)
return wrapper
return my_decorator
@decorator_maker_with_arguments("swadhikar", "c")
@makeupper
def hello(ar1, ar2):
return "Hello User!"
print hello('arg1', 'arg2')
输出:
I am a decorator maker and you passed "swadhikar:c" while calling me...
I am the wrapper and I can access the method args "arg1:arg2"
HELLO USER!