当前位置:编程学习 > python >>

Python: class and type

 "类/class" ?
"类型/type" ?

在搞明白之前,我们先看一个简单的例子。(以下所提都是 new-style User-defined classes)

>>> class My(object):
...     def test(self):
...         print "My"
...

>>> My
<class __main__.My>

>>> My2 = type("My2", (My,), {"x": 1234})

>>> My2
<class __main__.My2>

>>> My2.__bases__
(<class __main__.My>,)

>>> My2().test()
My
我们会发现 Python "class statement(指令)" 和 "function type(name, bases, dict)" 实际上做的是同一件事: 生成一个 "类型对象"。

抛开 Python 早期版本中的痼疾,我们可以把 "类/class" 和 "类型/type" 当作同一个事物在不同时期的两个称呼。"类型/type" 自然是运行期的一个概念,它持有相同类实例对象的公有信息,如静态字段、方法成员 (含实例和静态方法,参考《Python Essential: 7. Classes (1)》) 等。换句话说,我们可以 "认为" class statement block 是一个包装了 "type(...)" 操作的 "语法糖"。

class = type(classname, superclasses, attributedict)
那么上面例子中的 "My" 和 "My2" 在运行期就应该被称为 "类型/type", 它们实际上是 "type class" 的对象实例 (在 Python 里什么都是对象,包括类型对象本身)。

>>> isinstance(My, type)
True

>>> isinstance(My2, type)
True
要分清 "type(...) 创建自定义类型对象" 和 "类继承" 的区别,可以认为 "继承" 是一种 "数据契约",而 "type(...)" 执行时会参考这些契约在目标类型对象中生成特定的成员,以便实现 mro 之类的查找规则。因此,My2 同样也是由 type(...) 创建的,而不是 My。在类型中分别用 __class__ 和 __bases__ 来存储创建该类型对象所使用的 type 和基类信息。

默认所有自定义类型 (无关继承层次) 都是有 type 创建的,但可以通过 metaclass 修改,详情参考《Python Essential: 11. Metaclasses》。

>>> class MyType(type):
...     pass
...

>>> My3 = MyType("My3", (My2,), {})

>>> My3.__class__
<class __main__.MyType>

>>> My3.__bases__
(<class __main__.My2>,)

>>> class My4(My):
...     __metaclass__ = MyType
...    

>>> My4.__class__
<class __main__.MyType>

>>> My4.__bases__
(<class __main__.My>,)
我们梳理一下思路:

1. 所有的自定义类型都是 type 类型的对象实例,比如 My、My2。
2. My 和 My2 通过查找 __bases__ 中的信息来确定是否具备类 "继承关系"。
3. 然后通过调用 My()、My2() 来生成我们实际所需的类实例对象。
4. 类实例对象仅存储实例字段,公用信息都保存在类型对象的字典中。

总结: (用英文更清楚地表达一下)

1. Classes Are Instances of type.
2. User-defined classes are instances of type classes.
3. User-defined classes are types that generate instances of their own.

----- 分隔线,休息一下 ------------------------------

好了,我们现在知道 type 是个特殊的系统对象,它是 "上帝",它创造了 "万物"。等等,那 object 呢?不是说 "object 才是一切的根" 吗?

宇宙中首先诞生了一个概念: 根类型(object class),可以看作是万物的本源雏形。接下来,生出一个怪物,这个怪物照着这个本源的样子创造了自己(type)。怪物取名叫 "上帝",还把本源变成了人(object type)。为了打麻将方便,照着 object type 的样子,又捏造 "二叔"、"三舅"、"四大姨"、"儿子"、"孙子" 之类的。(这不是打麻将,是要开赌场)

头晕吧?这就是 "先有蛋,还是先有鸡" 的由来。

>>> issubclass(type, object)
True

>>> isinstance(object, type)
True
好吧,我承认这很无聊。type 这个类型继承自 object,同时 object 这个类型又是由 type 创建的。

注意:这篇文章所涉及概念仅限 Python 2.5 以上版本,非 Python 的不同语言可能有不同的解释。另外,所说也不是很严谨,纯粹为了简单说明一个概念,有投机取巧的嫌疑。

补充:Web开发 , Python ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,