本文主要想解决的问题是:在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
的实例,并且没有父类。
三条规则
那么这些发现有什么用呢?我们需要引入以下三条规则
- 若对象
X
是类A
的实例,类A
继承类B
,则对象X
是类B
的实例(子类的实例是实例) - 若类
A
继承类B
,类B
是类M
的实例,则类A
是类M
的实例(实例的子类是实例) - 若类
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__
方法,见这里。