python - 如何测试 functools.partial 生成预期的函数对象

标签 python unit-testing arguments functools

当从一个 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().argspartial().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/

相关文章:

reactjs - React 输入组件单元测试值始终未定义

asp.net - 将单元测试慢慢集成到项目中所需采取的步骤

javascript - 函数的默认参数值、解构赋值

c 控制台应用程序自动完成动态参数

python - 将 json 的结果写入 csv

python - 如何提取字符串中整数值的第二个实例

python - 如何将文件中的文本行附加到两个特定行之间的列表?

java - 模拟方法返回 null 而不是预期的

python - 更改python中参数(列表)的值

python - 使用 PRAW 在 Python 中从 Reddit API 解码 JSON