解析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