python functools wrap_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

functools.partial的作用和tensorflow的slim很像,主要作用就是简化函数,更少更灵活的函数参数调用。

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

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-8

def 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),其他的输出结果相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值