首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

深入理解python中的类和对象

刚开始学习python的时候或者其他编程面向对象的编程语言的时候,难免会对类和对象理解得不太清楚。所以今天和大家分享下python中的类和对象,深入理解下python中的类和对象。

1.鸭子类型

当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。这个就是鸭子类型的定义,在python中,并不关心这个对象是什么类型,只关心他的行为。由行为来推断出该对象所属于的类型。就比如列表(list)、元组(tuple)、字典(dict)等等,这些类都是可迭代的,所以说他们是可迭代对象。

2.类变量和实例变量

类变量就是在类内定义的,但是不在方法内定义的,而且前缀无self作为引用。实例变量就是有self作为引用的存在类中的变量。类变量是所有对象共享的,在类中修改时,其他的对象也会跟着变。但是需要注意的是,如果是用对象来引用类变量进行修改的话,这里只是新建了和类变量同名的实例变量,并没有修改到。下面用代码解释下。

上面的结果都是三个China,这个很容易知道,用类来引用改变时

修改后打印下三个结果都是修改后的结果。但是下面这个呢?

这次结果就不一样了,只有s1的类变量变了,其他两个都是不变的。这是为什么呢?就如上面所说,用实例引用来修改类变量的时候并不是修改,而是新建了这个变量。又由于python查找变量是由下往下查找的,所以会先查找出新建后的变量。

3.类属性和实例属性之间的访问顺序

类属性就是定义在类中的方法和变量,实例属性也是一样的。访问顺序就是由下往上查找的,用代码体会一下。

由于是类变量先加载,再到初始化对象,所以才会运行__init__()方法,所以结果很显然就是a。这里由于该类没有继承,就没有很复杂,但是当出现多继承,几个类之间就变得很复杂,这个时候的访问顺序就难多了。下面说下这两种情况,掌握了这两种情况,其他的基本没有问题了。

(1.适合深度优先查找

A继承了B,C,B,C分别继承了D,E。深度优先的查找是先去着A,如果A中没有该属性,就去B着,再没有就去D找。D中找不到了再去C找。这种查找情况是没有问题的,但是另一种情况就不合适了。

2)适合广度优先查找

这个是A继承了B,C,B,C都继承了D。如果这个用深度优先的算法的话,就会出现一个问题,因为深度优先查找顺序是A->B->D->C。这个是不太合理的,当C中重载了D中的一个方法后,B没有重载,如果要查找C中的该方法,用深度优先的算法就只能找到D中的原始方法,所以说这就不正确了,这时候就需要用广度优先的 算法,这个时候查找顺序就是A->B->C->D。但是当遇到上面的情况时又会出错了。这时怎么办?python3就将所有的属性搜索算法统一成了一个算法:C3算法,这里就不展开说这个算法了,因为太复杂了:)会根据对应情况而实施对应算法,下面用代码来分别体会下以上两种情况

__mro__这个属性是获取属性的查找顺序,可以看到就是和我们上面说的一样,用了深度优先的算法。再看另一个

这个时候就用了广度优先算法,符合与我们刚才所说的,这就是C3算法了哈。

4.super真的是调用父类吗?

学过Java的都知道,super()这个方法就是在调用父类的方法,但是在python中就不一定了。我们先看看super的用法

上面就是用法了,python2和python3用法不一样,这里我们就只用python3了就行操作。接下来看看super真正的调用情况。

上面这个是我们之前所说的那个适合广度优先算法的多继承,按照我们之前的理解,super调用的是父函数,那么这个结果就会是:

A B C D

显然是错误,结果是这个

是不是觉得很奇怪,但是又很熟悉?是的,这个也是按照刚才的查找顺序一样执行的,如果不信的话我们打印下__mro__就知道了

是不是刚好倒叙?因为我们是先打印父类的再打印自己的,所以顺序倒了。再看看另外一种情况也是可行的

也是和预期一样的。总的来说,super不一定是调用父类,它的调用顺序也是遵循mro算法的,就是属性查找算法,和上文说的C3算法一致。

有任何问题欢迎在留言区提问,或者有不当的地方也欢迎指出

ps:如果觉得文章不错的话,欢迎随手点赞转发支持

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180801A0DPWI00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券