当从一个 API 转到另一个 API 时,有时在每个 API 中的相似关键字之间进行映射会很有帮助,允许一个 Controller API 灵活地分派(dispatch)到其他库,而无需用户在幕后对不同的 API 大惊小怪。
假设某个库 other_api
有一个名为 "logarithm"
的方法,我需要从我的代码中提取出基数的关键字参数,例如“log_base_val”
;为了从 other_api
使用它,我需要输入(例如):
other_api.logarithm(log_base_val=math.e)
考虑这样一个玩具类:
import other_api
import math
import functools
class Foo(object):
_SUPPORTED_ARGS = {"base":"log_base_val"}
def arg_binder(self, other_api_function_name, **kwargs):
other_api_function = getattr(other_api, other_api_function_name)
other_api_kwargs = {_SUPPORTED_ARGS[k]:v for k,v in kwargs.iteritems()}
return functools.partial(other_api_function, **other_api_kwargs)
使用 Foo
,我可以映射一些其他 API,其中此参数始终称为 base
,如下所示:
f = Foo()
ln = f.arg_binder("logarithm", base=math.e)
和ln
在逻辑上等同于(log_base_val=math.e
in kwargs
,来自functools
) :
other_api.logarithm(*args, **kwargs)
但是,通过调用 functools
手动绑定(bind)相同的参数将导致不同的函数对象:
In [10]: import functools
In [11]: def foo(a, b):
....: return a + b
....:
In [12]: f1 = functools.partial(foo, 2)
In [13]: f2 = functools.partial(foo, 2)
In [14]: id(f1)
Out[14]: 67615304
In [15]: id(f2)
Out[15]: 67615568
因此 f1 == f2
的测试不会按预期成功:
In [16]: f1 == f2
Out[16]: False
所以问题是:测试参数绑定(bind)函数是否产生了正确的输出函数对象的规定方法是什么?
最佳答案
partial()
对象的 func
属性是对原始函数对象的引用:
f1.func is f2.func
函数对象本身不实现 __eq__
方法,因此您也可以只使用 is
来测试身份。
同样,partial().args
和 partial().keywords
包含调用时要传递给函数的参数和关键字参数。
演示:
>>> from functools import partial
>>> def foo(a, b):
... return a + b
...
>>> f1 = partial(foo, 2)
>>> f2 = partial(foo, 2)
>>> f1.func is f2.func
True
>>> f1.args
(2,)
>>> f2.args
(2,)
>>> f1.keywords is None
True
>>> f2.keywords is None
True
关于python - 如何测试 functools.partial 生成预期的函数对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22693499/