我正在学习装饰器,在这里我试着将下面的模式改为装饰器模式。
def invert(x):
return 1/x
print invert(5)可以使用装饰器进行更改。
def safe(fun, *args):
if args[0]!=0:
return fun(*args)
else:
"Division by 0"
def invert(x):
return 1/x
print safe(invert, 5) 使用@wapper语法,
def safe(fun, *args):
if args[0]!=0:
return fun(*args)
else:
"Division by 0"
@safe
def invert(x):
return 1/x
print invert(5)上面的代码给出了错误IndexError: tuple index out of range。我正在试图理解是什么让它错了,以及如何纠正它。
发布于 2012-06-21 18:48:43
您的主要问题是装饰器需要返回一个函数,而不是一个值。装饰器将定义的函数替换为基于它的新函数。
除此之外,else块中没有return语句,只有一个字符串文字。你可能是想把它还回去。
def safe(fun):
def f(*args):
if not args[0] == 0:
return fun(*args)
else:
return "Division by 0"
return f作为说明,我假设这只是为了练习的目的,但是错误不应该在Python中静默传递-发出异常的行为通常比在错误时返回字符串更有用。事实上,要在Python中更自然地实现这一点,您需要遵循的是请求宽恕,而不是允许的咒语:
def safe(fun):
def f(*args):
try:
return fun(*args)
except ZeroDivisionError:
return "Division by 0"
return f此外,要注意像“safe”这样的语句名称--其他异常仍然可能被抛出。
发布于 2012-06-21 18:59:52
你做错了。
def safe(fun):
def wrapper(*args)
if args[0]!=0:
return fun(*args)
else:
return "Division by 0"
return wrapper函数safe会为您用它修饰的每个函数调用一次。然后,每次调用修饰后的函数时,都会调用由safe返回的内部函数--这里称为wrapped。它负责调用原始函数,或者执行完全不同的操作。
因此,装饰器只有一个参数:要包装的函数。但是,还有装饰器函数,这是一个返回装饰器的函数(所以多了一层包装函数):
def safe(singularities):
def decorator(fun):
def wrapper(*args)
if args[0] not in singularities:
return fun(*args)
else:
return "Division by 0"
return wrapper
return decorator因此,safe装饰器函数现在可能返回无限数量的不同装饰器。像这样使用:
@safe([0])
def invert(x):
return 1 / x
@safe([-1, 1])
def foo(x)
return 1 / ((x - 1) * (x + 1))对于那些想知道为什么我在Lattyware发布了他的答案后发布了本质上与Lattyware相同的答案的人来说:这个答案直到我开始写我的答案之后才解决了所有的问题,现在我添加了比他的更多的信息,所以我不会删除它,因为它不是完全重复的。
https://stackoverflow.com/questions/11136479
复制相似问题