Python中的类型与类

19 投票
3 回答
37716 浏览
提问于 2025-04-16 08:43

我对Python中的类型和类有点困惑。比如,下面这个REPL对话让我感到困惑:

>>> class A: pass
... 
>>> a = A()
>>> type(a)
<type 'instance'>
>>> a.__class__
<class __main__.A at 0xb770756c>
>>> type([])
<type 'list'>
>>> [].__class__
<type 'list'>
>>> type(list)
<type 'type'>
>>> list.__class__
<type 'type'>
>>> type(A)
<type 'classobj'>
>>> A.__class__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: class A has no attribute '__class__'
  1. 为什么内置的东西(比如这里的列表)的类型和类是一样的,而用户自己定义的类/类型却不一样呢?
  2. 难道每个类不是都是某个其他类的实例吗(就像Java中的Class)?为什么用户定义的类没有__class__这个属性呢?

如果能解释一下或者推荐一些进一步的阅读材料来帮助我理解这个行为,我会非常感激。谢谢!

3 个回答

3

在Python 3.0中,用户自己定义的类的对象都是一种叫做“type”的东西的实例,而“type”本身也是一个类。

在Python 2.6中,新式类是从“object”这个东西继承来的,而“object”又是“type”的一个子类;

而经典类则是“type”的实例,但它们不是从类创建的。

4

这是因为“历史原因”。或者可能是“搞笑的原因”。在Python 3中,这些问题都已经解决了:

>>> class A: pass
... 
>>> a = A()
>>> type(a)
<class '__main__.A'>
>>> a.__class__
<class '__main__.A'>
>>> type([])
<class 'list'>
>>> [].__class__
<class 'list'>
>>> type(list)
<class 'type'>
>>> list.__class__
<class 'type'>
>>> type(A)
<class 'type'>
>>> A.__class__
<class 'type'>
>>> class B(object): pass
... 
>>> type(B)
<class 'type'>
>>> b = B()
>>> type(b)
<class '__main__.B'>
16

你遇到的新式类和旧式类的行为不一样。想了解更多,可以看看这个链接:Python 数据模型。特别是要关注类的部分,以及新式类和旧式类之间的区别。

试着在你的REPL(交互式编程环境)里输入以下内容:

class A: pass
class B(object): pass

你会发现结果是不同的。在这里,你正在处理新式类和旧式类之间的差异。在使用Python 2.6.1时,我得到的结果是:

> type(A)
<type "classobj">
> type(B)
<type "type">

这告诉你,列表是新式类,而不是旧式类。我们还可以用list来进一步实验:

> type(list)
<type "type">

这和我们的class B(object): pass的结果是一样的。而且还有

> c = []
> type(c)
<type "list">

这告诉你的是对象的实例,而不是它的定义。

撰写回答