2017-10-05 73 views
3

通常情況下,我可以不管三七二十一猴子補丁和模擬方法:爲什麼能在collections.MutableMapping的一個子類不是我猴子補丁__setitem__

from UserDict import DictMixin 
class py2fake_dict(DictMixin): 
    def __setitem__(self, name, value): 
     raise AssertionError("Don't talk to me!") 
    def __delitem__(self, name): 
     pass 
    def __getitem__(self, name): 
     pass 
    def __iter__(self): 
     yield None 
    def __len__(self): 
     return 0 

c = py2fake_dict() 
c.__setitem__ = lambda name, value: 'All clear.' 
# This is OK: 
c[1] = 2 

但是,如果有問題的方法是在MutableMapping子,我不能:

from collections import MutableMapping 
class py3fake_dict(MutableMapping): 
    def __setitem__(self, name, value): 
     raise AssertionError("Don't talk to me!") 
    def __delitem__(self, name): 
     pass 
    def __getitem__(self, name): 
     pass 
    def __iter__(self): 
     yield None 
    def __len__(self): 
     return 0 

c = py3fake_dict() 
c.__setitem__ = lambda name, value: 'All clear.' 
# This hits the assertion!!! 
c[1] = 2 

我從UserDict.DictMixin升級到collections.MutableMapping作爲我們Python3升級的一部分,當看到這個工作的代碼。我將刪除代碼,或將來使用子類,但我只想了解發生了什麼。

回答

2

你可以在類猴子補丁的方法就好了,但猴子修補上實例一new-style class因爲新式的類沒有工作的魔術方法均被引回到在Python 2.2。新風格的類是object及其後代,並且出於許多原因(更好的性能,更少奇怪的邊緣情況,支持新功能(如superproperty設置器,Python 3兼容性)),您應該更喜歡新風格類而不是舊風格可能。

UserDict.DictMixin是一箇舊式的類。對實例設置魔術方法只適用於舊式類的實例。 collections.MutableMapping是一種新式的課程。

在Python 3中,沒有舊式的類,所以你必須習慣魔法方法,只有在設置了類型的情況下才能使用。