%
的作用
% 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串.
百分号左边的字符串形式输出,右边的以变量的值输出。
重要理解带参数的装饰器
这就是带参数的装饰器,其实就是在装饰器外面多了一层包装,根据不同的参数返回不同的装饰器。
def wrap_in_tag(tag):
def decorator(func):
def wrapped(*args, **kwargs):
ret = func(*args, **kwargs)
return '<' + tag + '>' + ret + '</' + tag + '>'
return wrapped
return decorator
我们可以根据需要生成想要的装饰器了:
makebold = wrap_in_tag('b') # 根据 'b' 返回 makebold 生成器
# 调用wrap_in_tag()返回一个装饰器函数。
@makebold
def hello(name):
return 'hello %s' % name
>>> hello('world')
'<b>hello world</b>'
上面形式简写
@wrap_in_tag('b')
def hello(name):
return 'hello %s' % name
最外面的那层就是用来更换装饰器的标签的。
要点:
①装饰器本身就是一个函数
②函数里面可以定义函数
③注意区别带参数的装饰器和带参数的被包装函数
多个装饰器:
@decorator_one
@decorator_two
def func():
pass
等价于下面的
def func():
pass
func = decorator_one(decorator_two(func)
相当于嵌套函数,离被包装函数越近的装饰器越包装在里面(越早调用)
装饰器的副作用
函数 hello 被 makeitalic 装饰后,它的函数名称已经改变了:
def makeitalic(func):
def wrapped():
return "<i>" + func() + "</i>"
return wrapped
@makeitalic
def hello():
return 'hello world'
>>> hello.__name__
'wrapped'
为了消除这样的副作用,Python 中的 functools 包提供了一个 wraps 的装饰器:
from functools import wraps
def makeitalic(func):
@wraps(func) # 加上 wraps 装饰器
def wrapped():
return "<i>" + func() + "</i>"
return wrapped
@makeitalic
def hello():
return 'hello world'
>>> hello.__name__
'hello'
wraps 起到的作用是装饰完了之后,去掉多余的装饰部分,使被装饰器包装后的函数重新指向它原来的函数。
参考
装饰器