为什么以下代码不起作用?
+ [UIImage animatedImageNamed:duration:]
我想我在这里遵循关于模仿魔术方法的文档。文档做表示试图模拟不在规范中的魔术方法是行不通的。但是为什么>>> from mock import *
>>> class A(object):
... pass
...
>>> mock = create_autospec(A)
>>> mock.foo = Mock() # this works
>>> mock.__bar__ = Mock() # this works too
>>> mock.__subclasses__ = Mock() # this fails
AttributeError: Mock object has no attribute '__subclasses__'
不会出现在自动指定的新式类的规范中?
答案 0 :(得分:1)
__subclasses__
不是类规范的一部分。它是类的元类型的一部分(此处为type
)。
Python总是looks up special methods on the type,永远不会直接。如果Python需要调用__subclasses__
,它不会直接调用它,它会使用type(classobj).__subclasses__(classobj)
来查找未绑定的方法并手动传入第一个参数。因此,将__subclasses__
添加到类的模拟中是不够的。
这同样适用于打算对实例进行操作的特殊方法;使用Mock
时,__add__
会愉快地使用__str__
或create_autospec()
,然后在Python将使用的模拟类的实例中使用type(mockinstance).__str__(mockinstance)
{ {1}}调用__str__
方法。
如果您自己的代码直接调用classobj.__subclasses__()
,则您需要传入一个显式设置该方法的类模拟;你不能指望它在这里自动编制。
模拟不喜欢你设置任何有效的魔术方法:
>>> m = create_autospec(A)
>>> m.__add__ = Mock()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/mj/Development/venvs/stackoverflow-2.7/lib/python2.7/site-packages/mock.py", line 767, in __setattr__
raise AttributeError("Mock object has no attribute '%s'" % name)
AttributeError: Mock object has no attribute '__add__'
只允许使用非默认魔术方法:
>>> m.__dummy__ = Mock()
>>> m.__dummy__
<Mock name='mock.__dummy__' id='4427608656'>
您可以使用A
方法创建__subclass__
的子类,以便模拟它:
>>> class AMockSpec(A):
... def __subclasses__(self): pass
...
>>> m = create_autospec(AMockSpec)
>>> m.__subclasses__ = Mock()
>>> m.__subclasses__.return_value = ['SomeMockValue']
>>> m.__subclasses__()
['SomeMockValue']
答案 1 :(得分:0)
以下工作正常(__subclasses__
上提供__class__
):
>>> from mock import *
>>> class A(object):
... pass
...
>>> m = create_autospec(A)
>>> m.__class__.__subclasses__()
[]
>>> class B(A): pass
...
>>> m.__class__.__subclasses__()
[<class '__main__.B'>]
>>> m.__class__.__subclasses__ = Mock()
>>> m.__class__.__subclasses__()
<Mock name='mock()' id='4372594896'>