2014-10-11 113 views
2

在Python3.4:爲什麼類型(mock.MagicMock())== mock.MagicMock返回False?

>>> import mock.MagicMock 
>>> type(mock.MagicMock()) == mock.MagicMock 
False # Huh, why is that? 
>>> isinstance(mock.MagicMock(), mock.MagicMock) 
True 

當我簡化這ABtype(B()) == B回報True

>>> class A: pass 
>>> class B: pass 
>>> class C(A, B): pass 
>>> type(B()) == B  
True # Of course I would say. 

爲什麼返回type(mock.MagicMock()) == mock.MagicMockFalse?我知道Python中的difference between isinstance() and type()type()不明白子類別isinstance的作用。但我不明白這裏涉及的是什麼差別。

sourcemock.MagicMock

+0

請注意,類型(B())== B'在Python 2.7中爲「False」。 – 2014-10-11 22:36:05

+0

也許是另外一個問題,爲什麼? – OrangeTux 2014-10-11 22:36:47

+0

@Simeon Visser和@OrangeTux在Python 3之前,'class C():pass'產生了一箇舊式類。每個舊式類都是類「classob」(而不是類「類型」)的實例,任何舊式類的每個*實例都是類「實例」的實例,而不是用於創建它的類。老式的類在3.0中被刪除了,所以'class C():pass'與'class C(object):pass'在2.2+中仍然是3.x,'type'的一個實例。 – 2014-10-12 01:15:25

回答

2

更多的實驗提出了答案。

>>> from unittest.mock import MagicMock as mm 
>>> mm1 = mm() 
>>> mm2 = mm() 
>>> type(mm1) 
<class 'unittest.mock.MagicMock'> 
>>> type(mm2) 
<class 'unittest.mock.MagicMock'> 
>>> type(mm1) == type(mm2) 
False 
>>> id(type(mm1)) 
53511896 
>>> id(type(mm2)) 
53510984 
>>> type(mm1) is mm1.__class__ 
True 
>>> mm 
<class 'unittest.mock.MagicMock'> 
>>> id(mm) 
53502776 

結論:MagicMock的每個實例都有一個'class',看起來像MagicMock,但不是。什麼是新的創建這樣的實例? MagicMock的子類Mock,它的子類NonCallableMock,它有這個新的方法。

def __new__(cls, *args, **kw): 
    # every instance has its own class 
    # so we can create magic methods on the 
    # class without stomping on other mocks 
    new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__}) 
    instance = object.__new__(new) 
    return instance 

new = ...語句創建cls參數具有相同的名稱和文檔字符串的子類。下一行創建此子類的單個實例。所以嘲笑遵循修正的平等而不是type(mm()) is mm

>>> mm.__bases__ 
(<class 'unittest.mock.MagicMixin'>, <class 'unittest.mock.Mock'>) 
>>> type(mm1).__bases__ 
(<class 'unittest.mock.MagicMock'>,) 
>>> type(mm1).__bases__[0] is mm 
True 
相關問題