2012-10-30 12 views
11

Ich verwende Python 2.7.3 unter Windows. Ich habe versucht, die magische Methode __instancecheck__ als eine Klassenmethode zu überschreiben. Aber ich kann es nicht funktionieren lassen.Klassenmethode __instancecheck__ funktioniert nicht

class Enumeration(int): 
    @classmethod 
    def __instancecheck__(cls, inst): 
     if type(inst) == cls: 
      return True 
     if isinstance(inst, int) and inst in range(0,10): 
      return True 
     return False 

print isinstance(1, Enumeration) # prints False 
print isinstance(1, Enumeration()) # prints True 

Ich nehme an, die erste Druckanweisung würde True erhalten. Aber es scheint, die magische Methode __instancecheck__ wird nicht aufgerufen. Und ich weiß nicht, warum die zweite Druckanweisung funktionieren kann, da die isinstance eine Klasse/einen Typ als zweiten Parameter annehmen sollte.

Weiß jemand, was das Problem ist? Vielen Dank.

Antwort

18

instancecheck muss in einer Metaklasse definiert werden? Aus dem gleichen Grund, warum Ihr zweites Beispiel funktioniert hat. Wenn Python wertet isinstance(A, B) es B übernimmt eine Aufgabe zu sein, für seine Klasse sucht und ruft __instancecheck__ auf dieser Klasse:

isinstance(A, B): 
    C = class-of(B) 
    return C.__instancecheck__(A) 

Aber wenn B eine Klasse selbst ist, dann seine Klasse C sollte eine Klasse einer Klasse sein, mit anderen Worten, eine Meta-Klasse!

5

Die docs sagen:

Beachten Sie, dass diese Verfahren von der Art (Metaklasse) einer Klasse nachgeschlagen. Sie können nicht als Klassenmethoden in der aktuellen Klasse definiert werden. Dies entspricht der Suche nach speziellen Methoden, die für Instanzen aufgerufen werden. Nur in diesem Fall ist die Instanz selbst eine Klasse.

class Enumeration(type): 
    def __instancecheck__(self, other): 
     print 'hi' 
     return True 


class EnumInt(int): 
    __metaclass__ = Enumeration 

print isinstance('foo', EnumInt) # prints True 

Warum ist das

:

http://docs.python.org/2/reference/datamodel.html#customizing-instance-and-subclass-checks

+0

Vielen Dank. @ thg435 hat mir ein gutes Beispiel gegeben und jetzt weiß ich, wie ich das erreichen kann. – adarliu

Verwandte Themen