转载须注明出处:@Orca_J35
1. 概述
在 Python 中,类(class)和实例(instance)可被划分为两种风格:old-style (classic) 和 new-style。[^3]
在 Python 2 中为了保证兼容性,同时存在旧式类和新式类。
- 如果继承列表为空,便会创建一个旧式类;
- 如果继承旧式类,便会创建一个旧式类。
- 如果继承"顶级类型" object,便会创建一个新式类;
- 如果继承新式类(类型),便会创建一个新式类。
在 Python 3 中移除了旧式类,仅保留新式类。如果继承列表为空,便会创建一个继承自 object 的新式类。
tips: 在 Python 2 和3 中内置类型均是新式类。
>>> type(int)
>>> type(list)
2. Old-Style
在 Python 2.1 及其之前,只有旧式(old-style)类可用,并且 "类(class)" 和 "类型(type)" 是两个完全不相干的概念。
2.1 旧式类
classic class (in Glossary of Python 2)
Any class which does not inherit from
object
. See new-style class. Classic classes have been removed in Python 3.
在旧式类 OldCls 中,没有 __class__
属性。type(OldCls)
的返回值表示 OldCls 的类型(type),且始终是
。由此可见,旧式类统一由一个独立的内置类型实现,即 types.ClassType
(也称为
)。
如果旧式类没有显式继承任何旧式类,则其父类列表 __bases__
为空。
>>> # in Python 2.7
>>> class OldCls: pass
>>> # 旧式类没有__class__属性
>>> type(OldCls)
>>> OldCls.__bases__
()
>>> import types
>>> types.ClassType
# 旧式类OldCls是元类types.ClassType的实例
>>> isinstance(OldCls, types.ClassType)
True
a. ClassType in Python 2
types.ClassType 是 Python 2 中特有的内置类型,在 types 模块中的定义如下:
'''在Python2的types模块中,ClassType的定义如下'''
class _C: # _C是旧式类
def _m(self): pass
ClassType = type(_C)
types.ClassType
是继承自 object 的新式类(类型),其类型是 type:
>>> # in Python 2.7
>>> import types
>>> types.ClassType
>>> types.ClassType.__bases__
(,)
>>> type(types.ClassType)
>>> types.ClassType is type
False
types.ClassType
是旧式类的元类,负责构造旧式类,旧式类均是该元类的实例。所以,旧式类的类型均是
。另外,该类型也可构造新式类。
>>> # in Python 2.7
>>> # types.ClassType构造旧式类
>>> OldCls = types.ClassType('Other_OldCls', tuple(), dict())
>>> type(OldCls)
>>> OldCls.__bases__
()
>>> # types.ClassType也可构造新式类,此时和type等效
>>> NewCls = types.ClassType('X', tuple((object,)), dict())
>>> type(NewCls)
>>> NewCls.__bases__
(,)
>>>
>>> # type只能构造新式类,若第二参数为空,则默认继承object
>>> Other_NewCls = type('X', tuple(), dict())
>>> Other_NewCls.__class__
>>> Other_NewCls.__bases__
(,)
types.ClassType
不可以被继承,不能基于 types.ClassType
派生自定义元类。
>>> class Metaclass(types.ClassType):pass
Traceback (most recent call last):
File "", line 1, in
class Metaclass(types.ClassType):pass
AttributeError: module 'types' has no attribute 'ClassType'
b. 三种等价定义方式
# in Python 2
class Old: pass
class Old:
__metaclass__ = types.ClassType
Old = types.ClassType('Old', (), {})
2.2 旧式实例
对于某个旧式类的实例 x 而言,x.__class__
表示 x 的类(class) ;而 type(x)
的返回值表示 x 的类型(type),且始终是
。由此可见,所有旧式实例与他们的类之间是相互独立的,旧式实例统一由一个独立的内置类型实现,即 types.InstanceType
(也称为 "
)
>>> # in Python 2.7
>>> class OldCls: pass
>>> OldCls().__class__
>>> type(OldCls())
>>> from types import *
>>> InstanceType
""
>>> # 旧式实例均通过InstanceType构造
>>> old_inst = InstanceType(OldCls)
>>> old_inst.__class__
>>> type(old_inst)
a. InstanceType in Python 2
types.InstanceType 是 Python 2 中特有的内置类型,在 types 模块中的定义如下:
'''在types模块中,InstanceType的定义如下'''
class _C: # _C是旧式类
def _m(self): pass
_x = _C()
InstanceType = type(_x)
types.InstanceType
是继承自 object 的新式类(类型),其类型是 type,不能被继承:
>>> # in Python 2.7
>>> import types
>>> types.InstanceType
>>> types.InstanceType.__bases__
(,)
>>> type(types.InstanceType)
通过 types.InstanceType
可为旧式类构造实例,但不会主动调用实例的 __init__
函数。所以,用户定义旧式类的实例的类型均是
:
>>> in Python 2.7
>>> class OldCls:
def __init__(self, a_str):
self.a_str = a_str
>>> insts = OldCls("hello")
>>> type(insts)
>>> insts.__class__
>>> # types.InstanceType仅构造旧式类的实例,不会主动调用实例的__init__方法
>>> Other_insts = types.InstanceType(OldCls)
>>> type(Other_insts)
>>> Other_insts.__class__
>>> Other_insts.__init__("whale")
>>> Other_insts.a_str
'whale'