为什么可以';Python修饰符是否可以跨定义链接?
为什么以下两个脚本不相等 (摘自另一个问题:)为什么可以';Python修饰符是否可以跨定义链接?,python,decorator,Python,Decorator,为什么以下两个脚本不相等 (摘自另一个问题:) def makebold(fn): def wrapped(): 返回“+fn()+” 退货包装 def MAKE斜体(fn): def wrapped(): 返回“+fn()+” 退货包装 @马克博尔德 @使斜体 def hello(): 返回“你好,世界” 打印hello()##返回hello world 还有一个装饰师: def makebold(fn): def wrapped(): return "<b&g
def makebold(fn):
def wrapped():
返回“+fn()+”
退货包装
def MAKE斜体(fn):
def wrapped():
返回“+fn()+”
退货包装
@马克博尔德
@使斜体
def hello():
返回“你好,世界”
打印hello()##返回hello world
还有一个装饰师:
def makebold(fn):
def wrapped():
return "<b>" + fn() + "</b>"
return wrapped
@makebold
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
@makeitalic
def hello():
return "hello world"
print hello() ## TypeError: wrapped() takes no arguments (1 given)
def makebold(fn):
def wrapped():
返回“+fn()+”
退货包装
@马克博尔德
def MAKE斜体(fn):
def wrapped():
返回“+fn()+”
退货包装
@使斜体
def hello():
返回“你好,世界”
print hello()##TypeError:wrapped()不接受任何参数(给定1个)
为什么我想知道?我编写了一个retry
decorator来捕获MySQLdb异常-如果异常是暂时的(例如超时),它将在休眠一点后重新调用该函数
我还有一个
modifies\u db
decorator,它负责一些与缓存相关的管理工作modifies\u db
用retry
修饰,因此我假设所有用modifies\u db
修饰的函数也会隐式重试。我哪里出错了?原因是makebold中的wrapped()不接受任何参数
当你像那样使用装饰器时,它可能会引起一些问题,我将发布一个如何实现你想要的东西的示例,请给我一点时间
下面是一个您需要的工作示例
def makebold(rewrap=False):
if rewrap:
def inner(decorator):
def rewrapper(func):
def wrapped(*args, **kwargs):
return "<b>%s</b>" % decorator(func)(*args,**kwargs)
return wrapped
return rewrapper
return inner
else:
def inner(func):
def wrapped(*args, **kwargs):
return "<b>%s</b>" % func(*args, **kwargs)
return wrapped
return inner
@makebold(rewrap=True)
def makeitalic(fn):
def wrapped(*args, **kwargs):
return "<i>%s</i>" % fn(*args, **kwargs)
return wrapped
@makeitalic
def hello():
return "hello world"
@makebold()
def hello2():
return "Bob Dole"
if __name__ == "__main__":
print hello()
print hello2()
请注意,makebold是唯一的递归修饰符。还要注意用法上的细微差别:@makebold()
与@makeitalic
问题在于将“makeitalic”(接受一个参数)替换为“makebold”中接受零参数的“wrapped”函数
使用*args、**kwargs
将参数传递到链的下游:
def wrapped(*args, **kwargs):
return "<b>" + fn(*args, **kwargs) + "</b>"
def包装(*args,**kwargs):
返回“+fn(*args,**kwargs)+”
第二个例子的问题是
@makebold
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
这里
makeitalic
使用makebold
装饰wrapped
好问题。几个月前,我在做自己的重试修饰符时遇到了相同的场景。这需要重试次数,因此问题本身与您的有点不同,但具有与下面所示相同的解决方案。问题比实际情况更严重。包装另一个装饰者还有一些问题。+1这正好指出了问题所在以及需要如何做。基本上,问题来自于认为decorators做函数合成,但他们没有。是的,这正是我想做的,是的,我误解了decorators==函数合成-1。。。过于复杂,“makeitalic”是粗体+斜体的一个坏名字。看看哪一个在几行代码中做同样的事情。
def wrapped(*args, **kwargs):
return "<b>" + fn(*args, **kwargs) + "</b>"
@makebold
def makeitalic(fn):
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped
def makeitalic(fn):
@makebold
def wrapped():
return "<i>" + fn() + "</i>"
return wrapped