2012-10-30 18 views
11

Używam Pythona 2.7.3 w systemie Windows. Próbowałem zastąpić magiczną metodę __instancecheck__ jako metodę klasy. Ale nie mogę sprawić, żeby to działało.metoda klasy __instancecheck__ nie działa

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 

Zakładam, że pierwsze polecenie print zostanie ustawione na True. Ale wygląda na to, że magiczna metoda nie jest wywoływana. I nie wiem, dlaczego druga instrukcja print może działać, ponieważ klasa isinstance powinna przyjąć klasę/typ jako drugi parametr.

Czy ktoś wie, na czym polega problem? Dzięki.

Odpowiedz

18

instancecheck muszą być zdefiniowane w metaklasą:

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


class EnumInt(int): 
    __metaclass__ = Enumeration 

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

Dlaczego tak jest? Z tego samego powodu, dlaczego twój drugi przykład zadziałał. Kiedy pyton ocenia isinstance(A, B) zakłada B być przedmiotem, szuka swojej klasie i wzywa __instancecheck__ w tej klasie:

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

Ale kiedy B jest sama klasa, to jej klasa C powinny być klasy do klasy, innymi słowy, meta-klasa!

5

Docs powiedzieć:

Należy zauważyć, że metody te są spojrzał na typ (metaklasa) z klasy. Nie można ich zdefiniować jako metod klasowych w rzeczywistej klasie. Jest to zgodne z wyszukiwaniem specjalnych metod, które są wywoływane w instancjach, tylko w tym przypadku instancja sama jest klasą.

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

+0

Dziękuję. @ thg435 dał mi dobry przykład i teraz wiem, jak to osiągnąć. – adarliu

Powiązane problemy