Ade*_*lin 8 python class python-2.7 python-3.x
我们知道这会创建一个类:
class X:
a = 1
Run Code Online (Sandbox Code Playgroud)
并且,在Python 3中,由于使用了新的样式类,因此会X
自动从继承object
,但是在Python 2中,它不会:
>>> X.__bases__ # Python 2
()
>>> X.__bases__ # Python 3
(<class 'object'>,)
Run Code Online (Sandbox Code Playgroud)
而我们也知道,我们可以使用类工厂动态创建这样的一个类:
X = type("X",(object,), {"a":1})
name^ ^bases ^ "class" body
Run Code Online (Sandbox Code Playgroud)
然而,如果我们忽略了object
在基地的元组就像我们用做class
语法,我们继承object
的python3和,出乎意料的是,在python2还有:
X = type("X", ( ), {"a":1})
^ empty bases tuple
Run Code Online (Sandbox Code Playgroud)
>>> X.__bases__ # Python 2
(<type 'object'>,)
>>> X.__bases__ # Python 3
(<class 'object'>,)
Run Code Online (Sandbox Code Playgroud)
我期望X.__bases__
在python 2中是空的。
而且它不是这样的文档化功能,我几乎无法在Internet上找到有关此功能的信息。
实际上,python的官方文档矛盾地指出:
基元组逐项列出基类并成为
__bases__
属性
但是,如上所示,它()
仍然会(<type 'object'>,)
在Python 2中生成,因此将它变成__bases__
属性并不是真的。
谁能解释这种行为?
让我们看看这个Python 2 shell。
>>> class X1:
... a = 1
...
... X2 = type('X2', (), {'a': 1})
>>> type(X1)
0: <type 'classobj'>
>>> type(X2)
1: <type 'type'>
>>> import types
>>> assert types.ClassType is type(X1)
Run Code Online (Sandbox Code Playgroud)
types.ClassType
被描述为:
用户定义的旧类的类型。
基本上type
在新样式类的默认元类中。如果要使用旧样式的元编程,则可以types.ClassType
以相同的方式使用。
>>> X3 = types.ClassType('X3', (), {'a': 1})
>>> X3.__bases__
2: ()
Run Code Online (Sandbox Code Playgroud)
作为参考,摘录自Python 2的New-class和classic类:
类和实例有两种风格:旧样式(或经典样式)和新样式。
在Python 2.1之前,的概念
class
与的概念无关type
,而旧式类是唯一可用的样式。对于老式类,该语句x.__class__
提供x的类,但type(x)
始终为<type 'instance'>
。这反映了一个事实,即所有旧式实例(独立于其类)均使用称为的单个内置类型实现instance
。新样式类在Python 2.2引入了统一的概念
class
和type
。新型类只是用户定义的类型,不多也不少。如果x是新样式类的实例,则type(x)
通常与x相同x.__class__
(尽管不能保证-允许新样式类实例覆盖为返回的值x.__class__
)。