python基础(functools)
推荐:[http://www.wklken.me/posts/2013/08/18/python-extra-functools.html]
由于经常在tensorflow的代码中看到functools这个函数,有不太明白就写了这个博文。
*************************************************传说中的分割线*********************************************
functools的常见函数:其中最常见的自然是functools.partial
- functools.partial
- functool.update_wrapper
- functool.wraps
- functools.reduce
- functools.cmp_to_key
- functools.total_ordering
functools.partial可以让我们通过包装的方法,减少你的函数参数。
源代码:
#args/keywords 调用partial时参数
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords) #合并,调用原始函数,此时用了partial的参数
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
【python基础(functools)】partial将你传入的参数保存,如果你需要使用的时候则添加进入。
示例:
def add(a, b):
return a + b
print add(4, 2)
plus3 = partial(add, 4)
plus5 = partial(add, 5)
print plus3(2)
print plus3(7)
print plus5(10)
# 6
# 6
# 11
# 15
type(plus3)
#
可以看出返回的其实是一个partial类型的变量,实际相当于在partial中保存了需要调用的函数以及参数,在需要调用的时候将预先设置的参数传入参数列表。
functool.update_wrapper 默认partial对象没有name和doc, 这种情况下,对于装饰器函数非常难以debug.使用update_wrapper(),从原始对象拷贝或加入现有partial对象
它可以把被封装函数的name、module、doc和 dict都复制到封装函数去(模块级别常量WRAPPER_ASSIGNMENTS, WRAPPER_UPDATES)
说白了就是没有加@functools.wraps的函数,装饰器@返回的是函数名是原本的但是其函数签名等内部参数说明却是装饰原函数的那个函数的。
使用了@functools.wraps的函数,它能够帮助你在装饰器@保存被装饰的函数的函数内部签名等信息。
#!/usr/bin/env python
# encoding: utf-8def wrap(func):
def call_it(*args, **kwargs):
"""wrap func: call_it"""
print('before call')
return func(*args, **kwargs)
return call_it@wrap
def hello():
"""say hello"""
print('hello world')from functools import update_wrapper
def wrap2(func):
def call_it(*args, **kwargs):
"""wrap func: call_it2"""
print('before call')
return func(*args, **kwargs)
return update_wrapper(call_it, func)@wrap2
def hello2():
"""test hello"""
print('hello world2')if __name__ == '__main__':
# hello()
print(hello.__name__)
print(hello.__doc__)
# hello2()
print(hello2.__name__)
print(hello2.__doc__)
#call_it
#wrap func: call_it
#hello2
#test hello
functool.wraps 实验发现其实这个是对于update_wrapper的再次简化,与之前的函数有区别的地方在于:
def wrap2(func):
@functools.wraps(func)
def call_it(*args, **kwargs):
"""wrap func: call_it2"""
print('before call')
return func(*args, **kwargs)
return call_it
相当于@functools.wraps(func)这句话代替了update_wrapper(call_it, func),其他的输出结果相同。
推荐阅读
- python学习之|python学习之 实现QQ自动发送消息
- 逻辑回归的理解与python示例
- python自定义封装带颜色的logging模块
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- Python基础|Python基础 - 练习1
- Python爬虫|Python爬虫 --- 1.4 正则表达式(re库)
- Python(pathlib模块)
- python青少年编程比赛_第十一届蓝桥杯大赛青少年创意编程组比赛细则
- Java|Java基础——数组
- Python数据分析(一)(Matplotlib使用)