[Python-Dev] Semantic of isinstance (original) (raw)
Maric Michaud maric at aristote.info
Tue Jun 27 09:29:12 CEST 2006
- Previous message: [Python-Dev] Semantic of isinstance
- Next message: [Python-Dev] Semantic of isinstance
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Le mardi 27 juin 2006 05:38, Phillip J. Eby a écrit :
At 05:16 PM 6/26/2006 -0700, Martin Maly wrote: > >>> class D(object): > >... def getclass(self): >... print "D.getclass" >... return C >... class = property(getclass) >... > > >>> isinstance(D(), D) > >True > > >>> isinstance(D(), C) > >D.getclass >True > >isinstance in this case returns True to both C and D test. I would expect > >to see the class property being called in both cases and get: > >>> isinstance(D(), D) > >D.getclass >False > >but that's not the case for some reason.
That's because isinstance checks type(D()) and finds it equal to D -- this shortcuts the process. > It seems that the class is only accessed in some cases, but not > always, leading to what I think is a semantic inconsistency. It's not inconsistent - isinstance() checks class in addition to type() in order to allow proxying tricks like lying about your class. It therefore returns true if either your real type or your class matches, and as you can see, the real type is checked first. >class E(object): > def getbases(self): > print "E.getbases" > return () > bases = property(getbases) > >class C(object): > def getbases(self): > print "C.getbases" > return (E,) # C() claims: "E is my base > class" bases = property(getbases) > >class D(object): > def getclass(self): > print "D.getclass" > return C() # D() claims: "C() is my > class" class = property(getclass) > > >class F(object): pass > > >print "Test 1" >print isinstance(D(), E()) # testing against E() instance >print "Test 2" >print isinstance(D(), E) # testing against E class > >The output here is: > >Test 1 >E.getbases >D.getclass >C.getbases >False > >Test 2 >D.getclass >False > >In the 2nd test, D.getclass is called to get the class of D(), which >returns C() instance. At this point I would expect that C.getbases gets >called as bases are retrieved, which would return tuple consisting of >E and ultimately produce True result. As it happens, this is due to the fact that E is a type, while E() is not. There's an optimization in the isinstance() machinery that simply checks to see if D().class is a subtype of E. That's where your experiment fails. I'm not sure whether this behavior should be considered correct or not.
Python-Dev mailing list Python-Dev at python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/maric%40aristote.info
Doesn't seems to be just related to isinstance implementation, furthermore, it is very surprising that old-style and new style classes behave exactly the opposite way.
In [2]: class a(object) : ...: class = 0 ...: ...:
In [3]: a.class Out[3]: <type 'type'>
In [4]: a().class Out[4]: 0
In [7]: class a : ...: class = 0 ...: ...:
In [8]: a.class Out[8]: 0
In [9]: a().class Out[9]: <class __main__.a at 0xa78cb4ac>
--
Maric Michaud
Aristote - www.aristote.info 3 place des tapis 69004 Lyon Tel: +33 426 880 097
- Previous message: [Python-Dev] Semantic of isinstance
- Next message: [Python-Dev] Semantic of isinstance
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]