2016-07-08 8 views
1

Ich schrieb ein sehr einfaches Programm, um ein Wörterbuch zu untergliedern. Ich wollte die __missing__ Methode in Python versuchen. Nach einigen Recherchen fand ich heraus, dass es in Python 2 in defaultdict verfügbar ist. (In python 3 verwenden wir collections.UserDict though ..) Die __getitem__ ist die on verantwortlich für den Aufruf der __missing__ Methode, wenn der Schlüssel nicht gefunden wird.Python 2 __missing__ Methode

Wenn ich __getitem__ im folgenden Programm implementiere, bekomme ich einen Schlüsselfehler, aber wenn ich ohne es implementiere, bekomme ich den gewünschten Wert.

import collections 
class DictSubclass(collections.defaultdict): 

    def __init__(self,dic): 
     if dic is None: 
      self.data = None 
     else: 
      self.data = dic 

    def __setitem__(self,key,value): 
     self.data[key] = value 

    ######################## 
    def __getitem__(self,key): 
     return self.data[key] 
    ######################## 

    def __missing__(self,key): 
     self.data[key] = None 

dic = {'a':4,'b':10} 
d1 = DictSubclass(dic) 
d2 = DictSubclass(None)  
print d1[2] 

Ich dachte, ich __getitem__ umzusetzen benötigt, da es für den Aufruf __missing__ verantwortlich ist. Ich verstehe, dass die Klassendefinition von defaultdict eine __getitem__ Methode hat. Aber trotzdem, sagen wir, ich wollte meine eigene __getitem__ schreiben, wie würde ich es tun?

Antwort

7

Der dict Typ wird immer versuchen, __missing__ aufzurufen. All das defaultdict ist eine Implementierung bereitstellen; Wenn Sie Ihre eigene __missing__ Methode zur Verfügung stellen, müssen Sie defaultdict überhaupt nicht unterklassifizieren.

Siehe dict documentation:

d[key]
das Einzelteil von d mit Schlüssel Schlüssel. Erhöht eine KeyError, wenn Schlüssel nicht in der Karte ist.

Wenn eine Unterklasse von dict ein Verfahren und __missing__()Schlüssel definiert nicht vorhanden ist, der d[key] Betrieb ruft diese Methode mit dem Schlüssel Schlüssel als Argument. Die Operation d[key] gibt dann zurück oder erhöht, was durch den Aufruf __missing__(key) zurückgegeben oder ausgelöst wird. Keine anderen Operationen oder Methoden rufen __missing__() auf.

Allerdings müssen Sie die Standard __getitem__ Methode anstelle oder zumindest nennen es verlassen. Wenn Sie dict.__getitem__ mit Ihrer eigenen Version überschreiben und die Basisimplementierung nicht aufrufen, wird __missing__ nie aufgerufen.

Sie könnten __missing__ von Ihrer eigenen Implementierung nennen:

def __getitem__(self, key): 
    if key not in self.data: 
     return self.__missing__(key) 
    return self.data[key] 

oder man konnte die ursprüngliche Implementierung nennen:

def __getitem__(self, key): 
    if key not in self.data: 
     return super(DictSubclass , self).__getitem__(key) 
    return self.data[key] 

In Python 2 können Sie nur eine Unterklasse UserDict.UserDict:

from UserDict import UserDict 

class DictSubclass(UserDict): 
    def __missing__(self, key): 
     self.data[key] = None