【每日学一技】【001】Python中一切皆对象

1. 前言

今天主要是学习了 Python 中的对象(object)。编程是一种抽象建模的过程,在 Java 中对象的概念贯彻的非常彻底,每个 Java 类就是一个对象,充分体现了面向对象编程。Python 作为一门高级语言,自然也可以面向对象编程,也可以面向过程编程。了解 Python 的人基本都听说过一句话:Pyhton 中一切皆对象,老实说,以前我只记得这句话,但是并没有什么见解,仅仅停留在字面上,这不利于自己的成长,对于一名有追求的工程师,吃饭的家伙必须熟悉,因为也就有了这篇文章,这篇文章将介绍:

  1. Python 中的对象和面向对象中的对象有啥不同?
  2. Python 中有哪些对象?
  3. 元类是什么?
  4. Python 的对象模型

2. 面向对象 VS Python 中的对象

以下摘自 wiki 百科关于面向对象,以及对象和类的描述:

面向对象程序设计(Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。(Class):定义了一件事物的抽象特点。类的定义包含了数据的形式以及对数据的操作。对象是类的实例化。

经常听到的一个比方是:类就像模板,是一个抽象概念,对象就是用这个模板做出来的产品,是一个相对具象的概念。

面向对象的关键是我们要把现实世界中的一切,抽象为一个个对象,这很想生物中的物种分类:界门纲目科属种。比如:狗是一个类,那么你家养的宠物狗就是一个实例对象。类有属性和方法。属性是类的一些静态特征,是类的数据,对应狗的毛色、大小、性别等。方法是类的行为,是动态特征,通过类的方法,可以改变类的状态,对应狗跑步等行为。

面向对象 3 大基本特征继承封装多态。这部分不在这篇文章讨论范围。

说这么多只是想说,Python 也是一门面向对象的语言,这些概念在 Python 中也完全适用。那么 Python 中一切皆对象 这句话又是说的什么呢?

答案是:Python 中,面向对象的"类"和"对象"都是通过对象实现的!类在 Python 中也是对象。

3. Python 中对象的分类

Python 中一切皆对象,类也是对象,那么Python 中都有哪些对象呢?

Python 中的类有内置的类和自定义的类,内置的类如:int/dict/tuple/set;自定义的类:使用 class 定义的类。这些类,在 Python 中我们可以称之为 类型对象。

Python 中的类实例化之后得到的对象称为实例对象,比如:1024,{1, 2, 3},Dog() 等。

一张图总结如下:

在这里插入图片描述

代码演示如下:

In [1]: class Dog():  # 自定义类型对象
   ...:     pass
   ...:

In [2]: int  # 内置类型对象
Out[2]: int

In [3]: 1234  # 内置类型实例对象
Out[3]: 1234

In [4]: dog = Dog()  # 自定义类型实例对象

In [5]: type(dog)  # 可以通过 type() 函数查看一个对象的类型
Out[5]: __main__.Dog

In [6]: dog.__class__  # 也可以查看该对象的 __class__ 属性查看一个对象的类型
Out[6]: __main__.Dog

4. Python 对象模型

对象理论模型中,对象是通过类实例化得到的,这在Python 中也适用。通常我们可以用 type() 函数来查看一个对象的类型,或者通过 对象的 __class__ 属性。我们也可以用 isinstance() 函数来判断一个实例对象是否由某个类型直接实例化而来。

在 Python 中,所有对象的类型都收敛于 type。所以 type 也称为 元类 ,它站在了 Python 中类型金字塔顶端。所有对象按照类型追根溯源,最后都是得到 type。所以 Python 中对象只有三种身份:实例对象、类型对象,元类。看看下面的代码:

In [10]: type(1234)
Out[10]: int

In [11]: type(int)
Out[11]: type

In [12]: type(type)
Out[12]: type

In [13]: type(dog)
Out[13]: __main__.Dog

In [14]: type(Dog)
Out[14]: type
    
In [15]: isinstance(1234, int)
Out[15]: True

In [16]: isinstance(dog, Dog)
Out[16]: True

In [17]: isinstance(dog, type)  # 实例化对象 dog 不是由 type 直接实例化得到
Out[17]: False

In [18]: isinstance(Dog, type)  # 自定义类由 type 实例化而来
Out[18]: True

In [19]: isinstance(int, type)  # 内置类型由 type 实例化而来
Out[19]: True

In [20]: isinstance(type, type)  # type 也是由 type 实例化而来!
Out[20]: True

type 的类型还是 type,type 也是由 type 实例化而来,它连自己都没有放过!它是怎么做到的?这里留待后面源码分析(先埋坑)。

还有一句话,在 Python 中所有对象的继承都收敛于 object。object 站在了继承金字塔的顶端。可以通过 issubclass() 函数来判断一个类型是否是另一个类型的子类。注意,类型也是自己的子类!

In [21]: issubclass(int, object)
Out[21]: True

In [22]: issubclass(Dog, object)
Out[22]: True

In [23]: issubclass(type, object)
Out[23]: True

In [26]: issubclass(object, object)
Out[26]: True

In [28]: issubclass(int, int)  # 注意,类型也是自己的子类!
Out[28]: True

In [29]: int.__base__
Out[29]: object

In [30]: Dog.__base__
Out[30]: object

Python 中是支持多继承的,但是一般不建议这么用,这是一个历史包袱。那么怎么查看一个对象都继承了哪些类呢?可以通过以下三个方法:

  1. __base__:如果继承多个类,只返回显式继承的第一个类,如果是隐式继承 object 则返回 object。
  2. __bases__:以元组的形式返回所有显示继承的类,如果没有显式继承,则返回 object 元组。
  3. __mro__:mro 是 method resolution order,表示方法查找顺序,会从自身出发,追溯到最顶层的类,因此返回 自身,继承的基类,基类继承的基类,直到 object。
In [31]: class A:
    ...:     pass
    ...:

In [32]: class B:
    ...:     pass
    ...:

In [33]: class C(A, B):
    ...:     pass
    ...:

In [34]: A.__base__
Out[34]: object

In [35]: B.__base__
Out[35]: object

In [36]: C.__base__
Out[36]: __main__.A

In [37]: C.__bases__
Out[37]: (__main__.A, __main__.B)

In [38]: C.__mro__
Out[38]: (__main__.C, __main__.A, __main__.B, object)

In [39]: print(object.__base__)
None

通过上面的代码,很好的解释了上面几句话,同时我们发现,object 的所有对象的基类,但是不像 type,类型链上,type 也是有类型的,那就是 type。但是继承链上,object 没有继承 objet,而是 None,为什么呢?因为 Python 查找属性或者方法时,会追溯继承链,如果自身没有,就会按照 mro 顺序去基类查找,所以继承链一定要有个终点,不然就是死循环了。

最后用一张图总结 Python 中的对象模型:
在这里插入图片描述

5. 参考资料

  1. 《深度剖析CPython解释器》1. Python中一切皆对象,这里的对象究竟是什么?解密Python中的对象模型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值