调用它:
>>> foo('a', 'b')
foo called with cooked: a, standard: b
不过,想要的是让这个函数的第一个参数,变成“调制参数”,并且只剩下第二个参数。
通过 Python 标准库模块functools的类partial,可以做到。
>>> from functools import partial
用 partial 调制第一个参数:
>>> cooked1 = partial(foo, 'cooked_value1')
原函数 foo 的第一个参数,被调制成为函数 cooked1,foo 的第二个参数,成了 cooked1 的唯一参数。
>>> cooked1('value1')
foo called with cooked: cooked_value1, standard: value1
>>> cooked1('value2')
foo called with cooked: cooked_value1, standard: value2
可以用其他值,生成调制函数:
>>> cooked2 = partial(foo, 'cooked_value2')
>>> cooked2('value1')
foo called with cooked: cooked_value2, standard: value1
>>> cooked2('value2')
foo called with cooked: cooked_value2, standard: value2
原本一个函数,现在调制成了两个,事半功倍呵。
>>> cooked1('value3')
foo called with cooked: cooked_value1, standard: value3
>>> cooked1('value4')
foo called with cooked: cooked_value1, standard: value4
>>> cooked2('value5')
foo called with cooked: cooked_value2, standard: value5
>>> cooked2('value6')
foo called with cooked: cooked_value2, standard: value6
如法炮制,可由原函数生成任意多个调制函数。 做出函数调用顺序图
用同样的调制技术,对调制出的函数,再次进行调制,可以产生下一级调制函数,……,由此逐步形成函数调用顺序图:
>>> def bar(child_fun, a):
... print "bar called with:", a
... return child_fun(a)
注意,函数 bar 的第一参数是个引用,即函数名。用这个办法,可以调制任何参数:
(其中的 float 和 min 是 Python 的内建函数)
>>> bar_float = partial(bar, float)
>>> bar_float('123')
bar called with: 123
123.0
>>> bar_min = partial(bar, min)
>>> bar_min((3,2,5))
bar called with: (3, 2, 5)
2
也可以这样调制下级函数:
>>> bar_cooked1 = partial(bar, cooked1)
>>> bar_cooked1('abc')
bar called with: abc
foo called with cooked: cooked_value1, standard: abc
这意味着,可以创建任意深度的函数调用图:
>>> bar_bar_min = partial(bar, bar_min)
>>> bar_bar_min((3,2,5))
bar called with: (3, 2, 5)
bar called with: (3, 2, 5)
2