文章目录
- 一、模块简介
- 二、模块函数
-
- 1. `functools.lru_cache(maxsize=128, typed=False)`
- 2. `functools.partial(func, /, *args, **keywords)`
- 3. `functools.update_wrapper`
- 4. `@functools.wraps`
-
- 4.1 装饰器原型
- 4.2 装饰器定义
- 4.3 装饰器应用
- 三、参考资料
一、模块简介
The functools module is for higher-order functions: functions that act on or return other functions.
functools模块用于高阶函数,高阶函数顾名思义也是一种函数,不同的是,高阶函数可以作用于或者返回其他函数。
二、模块函数
1. functools.lru_cache(maxsize=128, typed=False)
functools.lru_cache(maxsize=128, typed=False)
2. functools.partial(func, /, *args, **keywords)
functools.partial(func, /, *args, **keywords)
3. functools.update_wrapper
functools.update_wrapper
4. @functools.wraps
@functools.wraps
这是一个装饰器。
4.1 装饰器原型
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
4.2 装饰器定义
This is a convenience function for invoking update_wrapper() as a function decorator when defining a wrapper function.
在定义装饰器函数内部的嵌套函数时,在嵌套函数上方使用@functools.wraps()相当于调用函数functools.update_wrapper()
It is equivalent to partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated).
这相当于partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)
4.3 装饰器应用
在Python装饰器从初识到精通中,我们知道使用装饰器可以为代码编写带来很大的便利, 但是使用装饰器时,也可能会影响到Python中的自省特性(特别在使用交互式Python shell时会用到该特性),这就可以通过使用@functools.wraps()装饰器来解决。
- 自省的概念:
所谓自省是指,Python中对象可以在运行时知道其各类属性。如:一个函数知道其自身名称以及帮助文档内容。
如:
In [1]: print
Out[1]: <function print>
In [2]: print.__name__
Out[2]: 'print'
In [3]: help(print)
- 自省的使用:
自省特性同样适用于用户自定义的函数,如:
In [5]: say_whee
Out[5]: <function __main__.say_whee>
In [6]: say_whee.__name__
Out[6]: 'say_whee'
- 当自省遇到装饰器:
但问题是:当对自定义函数使用装饰器后,将对say_whee()函数的自省特性产生影响,如:
def do_twice(func):
"""该装饰器用于将被装饰函数执行两次"""
def wrapper(*args, **kwargs):
func(*args, **kwargs)
func(*args, **kwargs)
return wrapper
@do_twice
def say_whee():
"""这是一个简单的被装饰函数"""
print("Whee!")
say_whee()
print("执行print(say_whee)后的结果为:")
print(say_whee, end="\n" * 2)
print("执行print(say_whee.__name__)后的结果为:")
print(say_whee.__name__, end="\n" * 2)
print("执行print(help(say_whee))后的结果为:")
print(help(say_whee))
上述程序的执行结果为:
Whee!
Whee!
执行print(say_whee)后的结果为:
<function do_twice.<locals>.wrapper at 0x7fe48aa679d8>
执行print(say_whee.__name__)后的结果为:
wrapper
执行print(help(say_whee))后的结果为:
Help on function wrapper in module __main__:
wrapper(*args, **kwargs)
None
即:由于对函数say_whee使用了装饰器do_twice的缘故,导致其原本的属性被遗失。
- 装饰器产生的问题用装饰器来解决:
使用@functools.wraps()装饰器即可以解决此问题(用魔法来打败魔法),如:
import functools
def do_twice(func):
"""该装饰器用于将被装饰函数执行两次"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
func(*args, **kwargs)
func(*args, **kwargs)
return wrapper
@do_twice
def say_whee():
"""这是一个简单的被装饰函数"""
print("Whee!")
say_whee()
print("执行print(say_whee)后的结果为:")
print(say_whee, end="\n" * 2)
print("执行print(say_whee.__name__)后的结果为:")
print(say_whee.__name__, end="\n" * 2)
print("执行print(help(say_whee))后的结果为:")
print(help(say_whee))
上述代码的执行结果为:
Whee!
Whee!
执行print(say_whee)后的结果为:
<function say_whee at 0x7f1360f8da60>
执行print(say_whee.name)后的结果为:
say_whee
执行print(help(say_whee))后的结果为:
Help on function say_whee in module main:
say_whee()
这是一个简单的被装饰函数
None
三、参考资料
- [1] Primer on Python Decorators