本文主要想解决的问题是:在Python中什么是“一切皆对象”?

什么是对象?

Python官方术语对照表中是这样定义的:

Object: Any data with state (attributes or value) and defined behavior (methods).

什么是属性(attribute)和方法(method):

Attribute: A value associated with an object which is usually referenced by name using dotted expressions.

Method: A function which is defined inside a class body. If called as an attribute of an instance of that class, the method will get the instance object as its first argument (which is usually called self).

什么是函数(function)和类(class):

Function: A series of statements which returns some value to a caller.

Class: A template for creating user-defined objects.

什么是语句(statement)和表达式(expression):

Statement: A statement is part of a suite (a “block” of code).

Expression: A piece of syntax which can be evaluated to some value.

另一种定义

有的地方(比如这里)会说:

An Object is an instance of a Class.

但什么是类(Class)呢?这里又说:

A class is a user-defined blueprint or prototype from which objects are created.

虽然这种定义在逻辑上有循环论证之嫌,但是我们接下来主要使用的还是第二种定义,稍后再说明这两种定义都是正确的甚至是等价的。

它们都是对象吗?

回到最初的问题“一切皆对象”。我们为了定义对象又引入了一堆新的定义,其中最重要的就是类(class),那么类是不是对象呢?按照定义我们只需要指出类是谁的实例就好了。

两个关系

我们需要引出面向对象编程(OOP)中的两个关系(Relationship):继承(inheritance)和实例(instantiation)

  • Inheritance (is-a-kind-of):(一个)类继承(一个或多个)类/(一个)类是(一个或多个)类的子类
  • Instantiation (is-a-instance-of): 对象是类的实例

Python中,可以使用

  • issubclass(classA, classB) 判断classA是不是classB的子类
  • isinstance(objectX, classA) 判断objectX是不是classA的实例

以及

  • __base__/__bases__返回类的直接父类(元组)
  • __class__返回对象所属的类

举个栗子:

def f(x):
 pass

print(f.__class__)

# <class 'function'>

说明函数f是类function的实例,故函数确实是对象。方法可以嵌套,于是:

print(f.__class__.__class__)
print(f.__class__.__class__.__class__)

# <class 'type'>
# <class 'type'>

说明类function是类type的实例,而类type是自己的实例!

那么__base__/__bases__呢?由于函数f不是类,只能对类function和类type使用:

print(f.__class__.__bases__)  
print(f.__class__.__class__.__bases__)
print(f.__class__.__class__.__base__.__class__)
print(f.__class__.__class__.__base__.__bases__)

# (<class 'object'>,)
# (<class 'object'>,)
# <class 'type'>
# ()

说明类function和类type都是类object的子类,而类object是类type的实例,并且没有父类。

三条规则

那么这些发现有什么用呢?我们需要引入以下三条规则

  1. 若对象X是类A的实例,类A继承类B,则对象X是类B的实例(子类的实例是实例)
  2. 若类A继承类B,类B是类M的实例,则类A是类M的实例(实例的子类是实例)
  3. 若类A继承类B,类B继承类C,则类A继承类C(子类的子类是子类)

结合上述三条规则,可以知道

  • 由于类type是类object是子类,类object是类type的实例,所以类type必须是类type的实例
  • type的实例也是类object的实例

什么是“一切皆对象”?

现在我们已经几乎能够回答这个问题了。如果说类type果真是原初对象,那么只要在类object中定义了属性和方法(类变量),那么Python中的所有"东西",通过继承或实例或别的什么关系得到的一切,都将拥有这两个“属性”,换言之,都是对象

我们一直没有给type一个名分,那就是元类metaclass,大道至简:

Metaclass: The class of a class.

即元类就是实例是类的类。尽管我们可以自己定义元类,但是其仍必须是类type的子类,因此我们可以说类type确实是原初对象,这也就回答了到底什么是“一切皆对象”。

原初对象

现在我们回到上面的三条规则,由于子类的子类是子类,所以继承关系可以无限延续下去~~(导致屎山)~~,但由于类type是自己的实例,实例关系是有限的。根据定义,最多只能有实例的实例。于是我们可以将所有对象分成三类:

  • 元类(metaclass):类type及其子类
  • 类(class):元类的实例及其子类
  • 非类(non-type):类的实例

也可以将元类和类放在一起,与非类区分开来,称为类(type)。这样做的意义是使得类是一个类type is a type,因此类type应该是类type的实例。并且:

class ’type’ is a type of all types.

class ‘object’ is a superclass of all types (except itself).

于是类type和类object可以看成是Python“一切皆对象”中的亚当和夏娃。

其他的什么

两种type

对于一个类,我们可以通过一些内置函数知道它究竟长什么样,比如__doc__,其返回模块(module)的docstring

print(type.__doc__)

# type(object) -> the object's type
# type(name, bases, dict, **kwds) -> a new type

说明类type有两种使用方法:

  • 一种是返回对象所在的类(type)
  • 一种是实例化,即创建新的类(class)

第一种用法本质上是调用了对象的__class__方法:

print(type(object) == object.__class__)

# True

所以在这个意义上type就是class

关于第二种用法见这里

对象是如何创建的?

使用__new____init__方法,见这里

参考

  1. Python官方术语对照表
  2. Python object
  3. Python Classes and Objects
  4. Python进阶——详解元类,metaclass的原理和用法
  5. Python Types and Objects
  6. What are Python Metaclasses?
  7. Python 进阶技巧: 类与继承
  8. 01 详解Python3中的__init__和__new__的区别