解析partial函数的实现
定位到Python Standard Library的6.6节, 即6.6 functools,
看这样一个函数:
def partial(func, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = keywords.copy()
newkeywords.update(fkeywords)
return func(*(args + fargs), **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
我们可以这样调用:
binary_to_int = partial(int, radix=16)
print hex_to_int('11111111')
从模式的角度看, partial是一个functor adapter!
为什么可以做到这一点?我们来看看partial的代码实现.
partial做了3件事情:
1. 定义newfunc函数
2. 保存func, args, 以及keywords
3. 返回newfunc函数
binary_to_int = partial(int, radix=16), 对于这样一个语句,
我们发现当partial返回newfunc给binary_to_int后, 传递给partial
的参数对于new_func已经不可见, 那么当binary_to_int被调用时,
newfunc中的args, keywords, func从哪里来呢?
答案是: 来自于binary_to_int自身! 因为binary_to_int保存了func, args, keywords.
这说明了两个问题: 1. newfunc是一个函数对象, 定义了3个属性; 2. 当定义
一个函数时, 编译器不检查函数体中涉及的变量的有效性, 而是等到实际调用
时进行check; 3. Python是名副其实的动态语言
# e.g
def test(arg):
def func():
print arg
func.arg = arg
return func