gpt4 book ai didi

python - 修补函数的 __call__

转载 作者:IT老高 更新时间:2023-10-28 20:33:39 26 4
gpt4 key购买 nike

我需要在测试中修补当前日期时间。我正在使用这个解决方案:

def _utcnow():
return datetime.datetime.utcnow()


def utcnow():
"""A proxy which can be patched in tests.
"""
# another level of indirection, because some modules import utcnow
return _utcnow()

然后在我的测试中,我会执行以下操作:

    with mock.patch('***.utils._utcnow', return_value=***):
...

但今天我想到了一个想法,我可以通过修补函数 utcnow__call__ 来简化实现,而不是额外添加一个 _utcnow.

这对我不起作用:

    from ***.utils import utcnow
with mock.patch.object(utcnow, '__call__', return_value=***):
...

如何优雅地做到这一点?

最佳答案

当您修补函数的 __call__ 时,您正在设置该 instance__call__ 属性。 Python 实际上调用了类上定义的 __call__ 方法。

例如:

>>> class A(object):
... def __call__(self):
... print 'a'
...
>>> a = A()
>>> a()
a
>>> def b(): print 'b'
...
>>> b()
b
>>> a.__call__ = b
>>> a()
a
>>> a.__call__ = b.__call__
>>> a()
a

将任何东西分配给 a.__call__ 是没有意义的。

但是:

>>> A.__call__ = b.__call__
>>> a()
b

TLDR;

a() 不调用 a.__call__。它调用 type(a).__call__(a).

链接

answer to "Why type(x).__enter__(x) instead of x.__enter__() in Python standard contextlib?" 中有一个很好的解释为什么会发生这种情况。 .

此行为记录在 Special method lookup 上的 Python 文档中。 .

关于python - 修补函数的 __call__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34261111/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com