我也许怀疑这是一个很好的使用案例装饰,但这里:
import string
SelfClosing = object()
def escapeAttr(attr):
# WARNING: example only, security not guaranteed for any of these functions
return attr.replace('"', '\\"')
def tag(name, content='', **attributes):
# prepare attributes
for attr,value in attributes.items():
assert all(c.isalnum() for c in attr) # probably want to check xml spec
attrString = ' '.join('{}="{}"'.format(k,escapeAttr(v)) for k,v in attributes.items())
if not content==SelfClosing:
return '<{name} {attrs}>{content}</{name}>'.format(
name = name,
attrs = attrString,
content = content
)
else: # self-closing tag
return '<{name} {attrs}/>'
实施例:
def makeBoldWrapper(**attributes):
def wrapWithBold(origFunc):
def composed(*args, **kw):
result = origFunc(*args, **kw)
postprocessed = tag('b', content=result, **attributes)
return postprocessed
return composed
return wrapWithBold
演示:
@makeBoldWrapper(attr1='1', attr2='2')
def helloWorld(text):
return text
>>> print(helloWorld('Hello, world!'))
<b attr2="2" attr1="1">Hello, world!</b>
与装饰常见的误解是,参数(attr1=...)
是参数给装饰@myDecorator
;事实并非如此。函数调用myDecoratorFactory(attr1=...)
的结果计算为someresult
,并成为匿名装饰器@someresult
。因此'带有参数的装饰器'实际上是装饰器工厂,它需要返回一个装饰器作为一个值。
可能不会伤害推'functools.wraps'那里... –
@JonClements好点。 – Marcin
你能解释一下装饰器的层次,包括functools装饰器吗? – Stephan