Learning Python - Mark Lutz [425]
...
>>> I = C()
>>> type(I) # Type of instance is class it's made from
>>> I.__class__ >>> type(C) # Class is a type, and type is a class >>> C.__class__ >>> type([1, 2, 3]) # Classes and built-in types work the same >>> type(list) >>> list.__class__ As you can see, in 3.0 classes are types, but types are also classes. Technically, each class is generated by a metaclass—a class that is normally either type itself, or a subclass of it customized to augment or manage generated classes. Besides impacting code that does type testing, this turns out to be an important hook for tool developers. We’ll talk more about metaclasses later in this chapter, and again in more detail in Chapter 39. Implications for type testing Besides providing for built-in type customization and metaclass hooks, the merging of classes and types in the new-style class model can impact code that does type testing. In Python 3.0, for example, the types of class instances compare directly and meaningfully, and in the same way as built-in type objects. This follows from the fact that classes are now types, and an instance’s type is the instance’s class: C:\misc> c:\python30\python >>> class C: pass ... >>> class D: pass ... >>> c = C() >>> d = D() >>> type(c) == type(d) # 3.0: compares the instances' classes False >>> type(c), type(d) ( >>> c.__class__, d.__class__ ( >>> c1, c2 = C(), C() >>> type(c1) == type(c2) True With classic classes in 2.6 and earlier, though, comparing instance types is almost useless, because all instances have the same “instance” type. To truly compare types, the instance __class__ attributes must be compared (if you care about portability, this works in 3.0, too, but it’s not required there): C:\misc> c:\python26\python >>> class C: pass ... >>> class D: pass ... >>> c = C() >>> d = D() >>> type(c) == type(d) # 2.6: all instances are same type True >>> c.__class__ == d.__class__ # Must compare classes explicitly False >>> type(c), type(d) ( >>> c.__class__, d.__class__ ( And as you should expect by now, new-style classes in 2.6 work the same as all classes in 3.0 in this regard—comparing instance types compares the instances’ classes automatically: C:\misc> c:\python26\python >>> class C(object): pass ... >>> class D(object): pass ... >>> c = C() >>> d = D() >>> type(c) == type(d) # 2.6 new-style: same as all in 3.0 False >>> type(c), type(d) ( >>> c.__class__, d.__class__ ( Of course, as I’ve pointed out numerous times in this book, type checking is usually the wrong thing to do in Python programs (we code to object interfaces, not object types), and the more general isinstance built-in is more likely what you’ll want to use in the rare cases where instance class types must be queried. However, knowledge of Python’s type model can help demystify the class model in general. All objects derive from “object” One other ramification of the type change in the new-style class model is that because all classes derive (inherit) from the class object either implicitly or explicitly, and because all types are now classes, every object derives from the object built-in class, whether directly or through a superclass. Consider the following interaction in Python 3.0 (code an explicit object superclass in 2.6 to make this work equivalently): >>> class C: pass ... >>> X = C() >>> type(X) # Type is now class instance was created from >>> type(C) As before, the type of a class instance is the class it was made from, and the type of a class is the type class because classes and types have merged.