修补函数的 __call__

Patch __call__ of a function(修补函数的 __call__)
本文介绍了修补函数的 __call__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I need to patch current datetime in tests. I am using this solution:

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()

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

Then in my tests I do something like:

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

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

But today an idea came to me, that I could make the implementation simpler by patching __call__ of function utcnow instead of having an additional _utcnow.

这对我不起作用:

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

如何优雅地做到这一点?

How to do this elegantly?

推荐答案

当你修补一个函数的 __call__ 时,你是在设置那个 __call__ 属性实例.Python 实际上调用了类上定义的 __call__ 方法.

When you patch __call__ of a function, you are setting the __call__ attribute of that instance. Python actually calls the __call__ method defined on the class.

例如:

>>> 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__ 是没有意义的.

Assigning anything to a.__call__ is pointless.

但是:

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

TLDR;

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

TLDR;

a() does not call a.__call__. It calls type(a).__call__(a).

回答为什么type(x).__enter__(x) 而不是 Python 标准 contextlib 中的 x.__enter__()?".

There is a good explanation of why that happens in answer to "Why type(x).__enter__(x) instead of x.__enter__() in Python standard contextlib?".

特殊方法查找的 Python 文档中记录了此行为.

这篇关于修补函数的 __call__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

patching a class yields quot;AttributeError: Mock object has no attributequot; when accessing instance attributes(修补类会产生“AttributeError:Mock object has no attribute;访问实例属性时)
How to mock lt;ModelClassgt;.query.filter_by() in Flask-SqlAlchemy(如何在 Flask-SqlAlchemy 中模拟 lt;ModelClassgt;.query.filter_by())
FTPLIB error socket.gaierror: [Errno 8] nodename nor servname provided, or not known(FTPLIB 错误 socket.gaierror: [Errno 8] nodename nor servname provided, or not known)
Weird numpy.sum behavior when adding zeros(添加零时奇怪的 numpy.sum 行为)
Why does the #39;int#39; object is not callable error occur when using the sum() function?(为什么在使用 sum() 函数时会出现 int object is not callable 错误?)
How to sum in pandas by unique index in several columns?(如何通过几列中的唯一索引对 pandas 求和?)