我想了解python装饰器。
我设计了一个简单的例子,我希望装饰器功能是一个自定义日志,只是打印错误,例如我尝试sum_和int
以及str
def log(fun):
try:
return fun(*args)
except:
print('error!')
@log
def sum_(a,b):
return a+b
这在我定义函数时已经很简单地返回"error"
。我怀疑我做了多少错误的事情......我试着调查关于那个主题的其他问题,但是我发现它们都很复杂,无法理解如何起草这样一个简单的例子,尤其是如何传递参数从原来的功能。
所有帮助和指示赞赏
答案 0 :(得分:3)
那是因为你没有将ByteBuffer
从函数转发给装饰器,而 catch-all 异常捕获 args
NameError
;始终指定异常类的原因之一。
以下是代码的修改版本,删除了try-catch并正确转发了函数参数:
args
答案 1 :(得分:2)
您收到错误的原因仅仅是因为装饰器中未定义args
。这与装饰器没什么特别之处,只是常规的NameError
。因此,您可能希望将异常子句限制为仅TypeError
s,这样您就不会消除其他错误。完整的实施将是
import functools
def log(fun):
@functools.wraps(fun)
def inner(*args):
try:
return fun(*args)
except TypeError:
print('error!')
return inner
@log
def sum_(a, b):
return a + b
使用functools.wrap
装饰器装饰内部函数也是一个好主意,装饰器将原始函数中的名称和文档字符串传递给装饰的函数。
答案 2 :(得分:1)
在这种情况下,log
装饰器不返回函数,而是返回值。这可能指向装饰器函数替换原始函数的假设,实际上,它被调用以创建替换函数。
可能代表意图的修正:
def log(fun):
def my_func(*args):
try:
return fun(*args)
except:
print('error!')
return my_func
在这种情况下,my_func
是为sum_(1, 2)
调用的实际函数,在内部,它调用装饰器接收的原始函数(原始sum_
)作为参数
一个简单的例子,说明了行动的顺序:
def my_decorator(fun):
print 'This will be printed first, during module load'
def my_wrapper(*args):
print 'This will be printed during call, before the original func'
return fun(*args)
return my_wrapper()
@my_decorator
def func():
print('This will be printed in the original func')