1. 关于本篇文章
解释了Python中的新风格objects:- <type 'type'>和<type 'object'>是什么。
- 用户自定义的类和实例之间、用户自定义的类和实例与内建类型之间是如何关联的。
- 元类(metaclasses)是什么。
2. 基本概念
2.1 Python中的object
那么Python object究竟是什么东西?Object是Python中的公理 - 它代表实体。但我们仍然可以通过下面几条来定义Python中的object:- 有标识(例如,给定两个名字我们可以确定它们是否指向同一个object)
- 有值(value)
- 有类型(type)
- 一个或多个bases.在面向对象中,你可以把这里的bases理解为基类或者超类。
Example 1.1. Examining an integer object
>>> two = 2>>> type(two) <type 'int'>
>>> type(type(two)) <type 'type'>
>>> type(two).__bases__ (<type 'object'>,)
>>> dir(two)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
Rule 1
Everything is an object
内建的int类型是一个object。但这并不代表仅仅是像2或者77这样的数字是objects,实际上还有另一个叫做int的object,它被保存在那些数字的值旁边(译者注:实际上,像int这种type object,多次运行id(int),其返回值是不会改变的)。所有的整型objects都有 __class__这一属性,而__class__值就是指向int的,用来表明“那家伙(int)懂我”。type()函数便是返回一个object的 __class__属性值。
我们定义的任何类都是objects。当然,这些类的实例也都是objects。甚至函数和方法也是objects。当然,各个objects并非是完全相同的。
2.2 A Clean Slate
现在我们从零开始构造Python的object system。先从一个空表格开始。
你也许会好奇为什么我要画这样一个图,这只是一个空图,后面我会逐步在上面加上不同的objects,并画出它们间的关系。(译者注:这里的三列从左到右分别代表metaclass,class,instance。metaclass可以理解成class的模板,一个class根据metaclass作为模板而生成出来。)
此时,让我们把之前我们了解的OOP知识先放一边,先从objects(我们定义的objects)和relationships开启此次学习之旅。
2.3 对象间的关系
我们使用两种relationships来连接不同的objects。一种是子类-父类(如:人是一种动物),一种是类型-实例(如Joe是一个人)。如果你对此概念不熟悉,可以先看看这里 the section called “Object-Oriented Relationships”。3. 引入对象
3.1 The First Objects
<type 'object'> and <type 'type'>.
Example 2.1. Examining <type 'object'> and <type 'type'>

![]() |
Whoa! What happened here? This is just Dashed Arrow Up Rule in action. Since <type 'type'> is a subclass of <type 'object'>, instances of <type 'type'> are instances of <type 'object'> as well. |
![]() |
Applying both Dashed Arrow Up Rule and Dashed Arrow Down Rule, we can effectively reverse the direction of the dashed arrow. Yes, it is still consistent. |
Class is Type is Class
type和class这两个术语在所有Python >= 2.3的版本中是一样的。 (译者注:然后作者又来唠叨了,其实这不是废话么?用过C++或者Java的都知道吧,不就是程序中要么是class要么是instance么。只是在Python中,class也是object而已。)还对判断类对象和非类对象感觉混淆吗?有一个简单的规则:
-
Type Or Non-type Test Rule
- 如果一个对象是<type 'type'>的实例, 那它就是类对象. 否则是非类对象。
回头看,可以证明这个规则对我们所碰到的所有对象都是成立的, 包括 <type 'type'>,它是自己的实例.
总结一下:
-
<type 'object'> 是 <type 'type'>的一个实例.
-
<type 'object'> 不是任何类的子类.
-
<type 'type'> 是自己的实例.
-
<type 'type'> 是 <type 'object'>的子类.
- python中只有两种对象: 为了清楚叫它们types 和 non-types. Non-types 也可以叫实例, 但实例这个术语也可以指向一个类对象, 因为一个type一定是另一个的type的实例. Types 也被叫做 classes, 并且我经常把他们叫做classes.
-
Note that we are drawing arrows on our slate for only the direct relationships, not the implied ones (i.e. only if one object is another's class, or in the other's bases). This make economic use of the slate and our mental capacity.
3.2 更多内置类型
Python中不止这两个对象,这两个基本对象有一堆的兄弟。

3.3 New Objects by Subclassing
C.__bases__ contains <type 'object'>, and MyList.__bases__ contains <type 'list'>.
在上例中,C.__bases__包含<type 'object'>,MyList.__bases__ 包含 <type 'list'>。
3.4 New Objects by Instantiating
除了继承外,还有别的方式创建新的object。(译者注:继承就是生成新的type-object,而这里所说的别的方式是指通过类生成新的实例) Example 2.5. Creating new objects by instantiating
我们注意C通过继承自<type 'object'>的object,其type会是<type 'type'>的实例,并且是自动成为<type 'type'>的实例。在下一节我会解释为什么。
3.5 It's All Instantiation, Really
| Q: | How does Python really create a new object? |
| A: | Internally, when Python creates a new object, it always uses a type and creates an instance of that object. Specifically it uses the __new__() and __init__() methods of the type (discussion of those is outside the scope of this book). In a sense, the type serves as a factory that can churn out new objects. The type of these manufactured objects will be the type object used to create them. This is why every object has a type. |
| Q: | When using instantiation, I specify the type, but how does Python know which type to use when I use subclassing? |
| A: | It looks at the base class that you specified, and uses its type as the type for the new object. In the exampleExample 2.4, “Creating new objects by subclassing” , <type 'type'> (the type of <type 'object'>, the specified base) is used as the type object for creating C.A little thought reveals that under most circumstances, any subclasses of <type 'object'> (and their subclasses, and so on) will have <type 'type'> as their type. |
Advanced Material Ahead
下面是一些高级内容,你可以直接跳到下一章。
<type 'type'>是所有类型的type,<type 'object'>是所有类型的基类。
- Python中有两种object:
- Type objects - 可以被继承,可以用来创建实例。
- Non-type objects - 不可以被继承,不可以用来创建实例。
<type 'type'>和<type 'object'>是两个最基础的object。objectname.__class__存在于每个object中,且指向此object的type。objectname.__bases__存在于每个type object中,且指向自己的父类。只有<type 'object'>的__bases__为空。- To create a new object using subclassing, we use the
classstatement and specify the bases (and, optionally, the type) of the new object. This always creates a type object. - To create a new object using instantiation, we use the call operator (
()) on the type object we want to use. This may create a type or a non-type object, depending on which type object was used. - Some non-type objects can be created using special Python syntax. For example,
[1, 2, 3]creates an instance of<type 'list'>. - Internally, Python always uses a type object to create a new object. The new object created is an instance of the type object used. Python determines the type object from a
classstatement by looking at the bases specified, and finding their types. issubclass(A,B)(testing for superclass-subclass relationship) returnsTrueiff:Bis inA.__bases__, orissubclass(Z,B)is true for anyZinA.__bases__.
isinstance(A,B)(testing for type-instance relationship) returnsTrueiff:BisA.__class__, orissubclass(A.__class__,B)is true.
- Squasher is really a python. (Okay, that wasn't mentioned before, but now you know.)
Example 3.1. More built-in types
>>> import types>>> types.ListType is list
True >>> def f():
... pass ... >>> f.__class__ is types.FunctionType
True >>> >>> class MyList(list):
... pass ... >>> class MyFunction(types.FunctionType):
... pass ... Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: type 'function' is not an acceptable base type >>> dir(types)
['BooleanType', 'DictProxyType', 'DictType', ..]
objectname.attributename, which object do we end up with? It all depends on objectname, its type, and its bases (if they exist).
Attribute access mechanisms in Python are explained in the second book of this series: Python Attributes and Methods.
types.ClassType object is in some ways an alternative <type 'type'>. Instances of this object (classic classes) are types themselves. The rules of attribute access are different for classic classes and new-style classes. Thetypes.ClassType object exists for backward compatibility and may not exist in future versions of Python. Other sections of this book should not be applied to classic classes.
Comment on this book here: discussion page. I appreciate feedback!
That's all, folks!
Can Skim Section
This oddly placed section explains the type-instance and supertype-subtype relationships, and can be safely skipped if the reader is already familiar with these OO concepts. Skimming over the rules below might be useful though.- is a kind of (solid line): Known to the OO folks as specialization, this relationship exists between two objects when one (the subclass) is a specialized version of the other (the superclass). A snake is a kind of reptile. It has all the traits of a reptile and some specific traits which identify a snake.Terms used: subclass of, superclass of and superclass-subclass.
- is an instance of (dashed line): Also known as instantiation, this relationship exists between two objects when one (the instance) is a concrete example of what the other specifies (the type). I have a pet snake named Squasher. Squasher is an instance of a snake.Terms used: instance of, type of, type-instance and class-instance.
We use the solid line for the first relationship because these objects are closer to each other than ones related by the second. To illustrate - if one is asked to list words similar to 'snake', one is likely to come up with 'reptile'. However, when asked to list words similar to 'Squasher', one is unlikely to say 'snake'. It is useful at this point to note the following (independent) properties of relationships:
Dashed Arrow Up Rule
If X is an instance of A, and A is a subclass of B, then X is an instance of B as well.Dashed Arrow Down Rule
If B is an instance of M, and A is a subclass of B, then A is an instance of M as well.Applying Dashed Arrow Up Rule, we can derive the second statement from the first:
- Squasher is an instance of snake (or, the type of Squasher is snake).
- Squasher is an instance of reptile (or, the type of Squasher is reptile).
Squasher.__class__issnake. (In Python, the__class__attribute points to the type of an object).- Both
isinstance(Squasher, snake)andisinstance(Squasher, reptile)are true.
Combine Solid Arrows Rule
If A is a subclass of B, and B is a subclass of C, then A is a subclass of C as well.snake.__bases__is(reptile,). (The__bases__attribute points to a tuple containing superclasses of an object).- Both
issubclass(snake, reptile)andissubclass(snake, animal)are true.
>>> type(two)
<type 'int'>
>>> type(type(two))
<type 'type'>
>>> type(two).__bases__
(<type 'object'>,)
>>> dir(two)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__',
'__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
'__floordiv__', '__format__', '__getattribute__', '__getnewargs__',
'__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__',
'__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__',
'__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__',
'__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__',
'__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__',
'__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
'__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
'__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
'conjugate', 'denominator', 'imag', 'numerator', 'real']
<type 'type'>
>>> type.__bases__
(<type 'object'>,)
