Python深入类和对象

一. 鸭子类型和多态

  1.什么是鸭子类型:

    在程序设计中,鸭子类型(英语:Duck typing)是动态类型和某些静态语言的一种对象推断风格。"鸭子类型"像多态一样工作,但是没有继承。“鸭子类型”的语言是这么推断的:一只鸟走起来像鸭子、游起泳来像鸭子、叫起来也像鸭子,那它就可以被当做鸭子。也就是说,它不关注对象的类型,而是关注对象具有的行为(方法)。

    可以看出,Cat,Dog,Duck中有相同的方法say(),当有一个函数调用Duck类时并调用say()方法,我们传入Cat类和Dog类也行,函数并不会检查对象是不是Duck,而是只要你有这样的方法就能运行。

  

如,列表的extend()方法只要参数是一个可迭代的对象就可以(list,set,tuple)

    还有前面的例子,只要实现了类中的__getitem__()魔法函数,就可以把类当作一个collection,实现啊__iter__和__next__就可以当作一个iterator。python中的鸭子类型允许我们使用任何提供所需方法的对象,而不需要迫使它成为一个子类。

  2.多态:

    由于python属于动态语言,当你定义了一个基类和基类中的方法,并编写几个继承该基类的子类时,由于python在定义变量时不指定变量的类型,而是由解释器根据变量内容推断变量类型的(也就是说变量的类型取决于所关联的对象),这就使得python的多态不像是c++或java中那样,定义一个基类类型变量而隐藏了具体子类的细节。

二. 抽象基类(abc模块)

  1.在某些情况下判断某个对象的类型:

    

 

  2.强制某个子类必须实现某些方法:

    

  3.模拟抽象基类:

     3.1利用内置抛错模拟:(但只有调用某些方法时才会抛异常)

      

 1 class CacheBase():
 2     def get(self,key):
 3         #默认抛出异常(Python内置错误)
 4         raise NotImplementedError
 5     def set(self,key,value):
 6         raise NotImplementedError
 7 #继承重写就不会抛异常
 8 class Rediscatche(CacheBase):
 9     def get(self,key):
10         pass
11     def set(self,key,value):
12         pass
13 cachebase=Rediscatche()
14 cachebase.set("key","value")

    3.2利用内置的abc模块:

 

    3.3通用的抽象基类(collections.abc模块,推荐使用多继承mixin,以防抽象基类设计过度):

      有可遍历,可哈希的等等抽象基类

 

 

        这些抽象基类都有一个魔法函数__subclasshook__():

      作用:Comp()没有继承Sized,但是却能判断出是Sized类型。

         __subclasshook__()会判断传入的C是否有“__len__”这个方法,有就返回为True

 

 

 

 

三. 使用isintance而不是type

   isinstance内部会去检查它的继承链,就可以判断它是A的类型,而type是指向B那个对象,判断是否和B是同一个对象。尽量应使用isinstance,而不是type,以免误判。

  

   is和==:

      is是判断两者是不是一个对象(即id是否相同),而==是判断值是否相同。如type(b)指向的是B这个对象,虽然B继承于A,但是A和B是两个不同的对象。         

四. 类变量和对象变量

  注:1.魔法函数__init__中self是实例化对象,中的参数是对象变量,在实例化后调用变量是向上查找(即先查找对象变量,后查找类变量),类变量可以直接通过类访问;

    2.类变量是所有实例共享的

通过类修改类变量

通过实例对象修改变量


五. 类属性和实例属性以及查找顺序

  1.向上查找,即先查找对象变量(实例属性),后查找类属性:

  2.多继承采用MRO(【Method Resolution Order】:方法解析顺序)算法:

    Python语言包含了很多优秀的特性,其中多重继承就是其中之一,但是多重继承会引发很多问题,比如二义性,Python中一切皆引用,这使得他不会像C++一样使用虚基类处理基类对象重复的问题,但是如果父类存在同名函数的时候还是会产生二义性,Python中处理这种问题的方法就是MRO。

DFS:深度优先算法,这样查询顺序为A->B->D->C->E

 

 这样就会出现问题(菱形继承):如果C继承D覆盖D中的某方法,在调用时是先查询D,然后查询C,则查询的方法是D中的,而不是C中重写的,因此在Python2

   后改成了广度优先的算法。

广度优先算法,这就解决了菱形继承,但是在第一种又出现了问题

如D和C中如果有个同名的方法,则会调用C中的方法,而不是D中的,而B是继承D的,因此从Python2.3后都统一为C3算法

  3.C3算法(参考:https://www.cnblogs.com/LLBFWH/p/10009064.html):  

    求某一类在多继承中的继承顺序:
    类的mro == [类] + [父类的继承顺序] + [父类2的继承顺序]
    如果从左到右的第一个类在后面的顺序中出现,那么就提取出来到mro顺序中
    [ABCD] + [EO] --> A = [BCD] + [EO]
    如果从左到右的第一个类在后面的顺序中出现,且在后面的顺序中也是第一位,那么就提出来到mro顺序中
    [ABCD] + [AEO] --> A = [BCD] + [EO]
    如果从左到右的第一个类在后面的顺序中出现,但不是在第一位,那么应该继续往后找,找到符合规则的项目
    [ABCD] + [EAO] --> E = [ABCD] + [AO]
    [ABCD] + [EAO] + [GEO] --> G = [ABCD] + [EAO] + [EO]
    [ABCD] + [EAO] + [EO] --> GE = [ABCD] + [AO] + [O]
    关键结论:
        这个类没有发生继承,他的顺序永远是[类o]
        只要是单继承,不是多继承,那么mro顺序就是从子类到父类的顺序

  4.查找顺序:

    4.1菱形继承:(Python2.3以前为经典类,默认不继承object(D),而2.3以后为新式类,默认继承object,即最后查找object类)

    

    4.2分别继承:

 

 

    

六. 静态方法、类方法以及对象方法

  1.实例方法:self为实例对象

  

 

  2.静态方法:(相当于普通的函数)

    (注:采用硬编码,如果类名改变,相应的静态方法中也要改变,如下面的Date改变,则parse_from_string中Date也相应改变)

    

利用外部对参数处理传入(每次都需要处理,麻烦)

 

利用静态方法

    静态方法用处:如在判断传入的参数是否为合法字符串,这是不用返回类对象,因此不用传入类(类方法)

      

 

  3.类方法:(传递的是类cls)

    注:相比静态方法,不是采用硬编码,无论类名称是什么,都不用修改类方法,且传递的是类(cls,只是名称,可以修改)

     

 

七. 数据封装和私有属性

  1.私有属性:

    

无法实例或类直接访问私有属性,只有通过类中的公共方法get_age间接访问

  2.私有属性原理:

    把具有双下划线的属性(如__birthday变为[_classname__attr]即_User__birthday),因此不是从语言层面解决了绝对私有性,只是加了一些小技巧。主要只是让我们书写更加规范,没有绝对的安全,也可以解决同样的变量名冲突的问题。如另一个类继承User,且也有__birthday,则根据规则是不一样的

    

仍然能访问

八. python对象的自省机制

  1.概念:

    自省是通过一定的机制查询到对象的内部结构

  2.__dict__,dir的使用:

    2.1通过dict查找属性:

   

实例的属性,但是通过name属性却能查找到(向上查找,name属性User类这个对象)

 

类属性,含有模板,文档,属性,弱引用等

     2.2通过__dict__添加修改属性:

      

 

     2.3通过dir查找属性(会列出所有属性,比__dict__更加详细): 

  

只有属性名称,没有属性值,还可以对list等使用

九. super函数

  

  1.如果想调用A中的构造函数:

      Python2:super(B,self).__init__()

          

      Python3中:super().__init__()

  2.既然重写A的构造函数,为什么还要调用super:

    很好的重用代码,如某个参数需要父类的构造函数处理,就可以调用super函数把参数交给父类的构造函数处理

    

将name交给Thread的构造函数处理

  3.super执行顺序: 

    super并不是直接调用父类,而是根据MRO算法的调用顺序(因此先是C,然后是A)

 

十. django rest framework中对多继承使用的经验

  1.建议:

    尽量不要使用多继承,以免造成混乱

  2.mixin多继承案例(如django restframework中的mixins):

    1.mixin类功能单一;

    2.不和基类关联,可以和任意基类组合,基类可以不和mixin关联就能初始化成功;

    3.在mixin中不要使用super函数;

    4.尽量以Mixin结尾

十一.python中的with语句

  1.try...except语句:

    except语句中将2压入堆栈中,finally又将4压入堆栈中,所以在取数据时直接从栈顶取数据,因此是4,如果没有finally则是前面的(如果要操作数据库,文件等,就需要在try中,except,finally中书写关闭连接,文件的逻辑)。

  2.上下文管理器:

    上下文管理器协议(需要实现两个魔法函数__enter__和__exit__):

      需要在__enter__中获取资源,在__exit__释放资源,只要满足这个协议就可以用with语句使用

       

 

                                  

十二. contextlib实现上下文管理器

    相当于简化__enter__和__exit__:@contextlib.contextmanager装饰器将__enter__和__exit__合起来并进行了一系列操作

 

十三.参考文献:

  MRO算法介绍

转载于:https://www.cnblogs.com/lyq-biu/p/10310174.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux中/usr下文件权限修改setuid导致的问题

2019独角兽企业重金招聘Python工程师标准>>> 在Ubuntu系统中因为一些原因我使用如下命令修改了/usr目录的拥有者权限: chown -R root:root /usr结果直接导致系统无法正常启动,通过跟踪系统启动日志/var/log/syslog找到如下失败原因&#xff1…

[转载]unix环境高级编程备忘:理解保存的设置用户ID,设置用户ID位,有效用户ID,实际用户ID...

转载自http://www.cnblogs.com/stemon/p/5287631.html 一、基本概念 实际用户ID(RUID):用于标识一个系统中用户是谁,一般是在登录之后,就被唯一的确定,就是登录的用户的uid。 有效用户ID(EUID):用于系统决定用户对系统…

django20:BBS网页设计/注册功能/验证码代码

表设计 注册功能 """ 1.注册功能需要forms组件 不同功能,可单独一个py文件2.利用forms组件渲染前端标签1.利用ajax提交2.forms组件获取用户数据的数据。$(#form).serializeArray()获取forms标签所有用户普通键值对的数据3. 手动渲染头像label里面内…

用最少的代码打造一个Mini版的gRPC框架

在《用最少的代码模拟gRPC四种消息交换模式》中,我使用很简单的代码模拟了gRPC四种消息交换模式(Unary、Client Streaming、Server Streaming和Duplex Streaming),现在我们更近一步,试着使用极简的方式打造一个gRPC框架…

Windows 10的下一个更新将在您观看视频时隐藏通知

Windows 10’s Focus Assist feature temporarily hides incoming notifications. In Windows 10’s next update, Focus Assist can activate when you’re using any full-screen app, whether that’s YouTube in a browser, Netflix, or a desktop video player like VLC. …

Ubuntu安装Samba文件共享服务器(NAS)

终于有点时间来解决下家中NAS需求了。一般自制NAS,只有选Samba。速度比FTP快,便利性比Windows文件夹共享好,设置多等等。 ▶参考:samba简介 安装Samba $ sudo apt-get update $ sudo apt-get install samba samba-common-bin 核心…

刚毕业的ERP实施顾问做甲方

我刚毕业进入了一家小公司做ERP实施顾问,是一个台湾的ERP软件,就简单培训了一天,第二天就进入一家客户公司解决问题,软件都还没有熟悉呢,更别说业务流程了,一天下来,人家员工问一个问题我记下来…

django21:admin后台管理\media配置\图片防盗链\暴露后端资源\路由分发\时间分类

admin后台管理 创建超级用户 createsuperuser 1.到应用下的admin.py注册模型表 from django.contrib import admin from blog import models # Register your models here.admin.site.register(models.UserInfo) admin.site.register(models.Article) admin.site.register(m…

Flask博客开发——Tinymce编辑器

之前Flask博客的文本编辑器比较简陋,这里为博客添加个优雅易用的Tinymce文本编辑器。 github见:https://github.com/ikheu/my_flasky 1 项目中添加Tinymce 下载好Tinymce包以及语言包,并添加到项目中。添加到项目的方法,参考了这篇…

Go开发Struct转换成map两种方式比较

最近做Go开发的时候接触到了一个新的orm第三方框架gorose,在使用的过程中,发现没有类似beego进行直接对struct结构进行操作的方法,有部分API是通过map进行数据库相关操作,那么就需要我们把struct转化成map,下面是是我尝…

Hello, Raspberry Pi.

1.概要最近在研究自动升级开源项目的时候偶然想到IoT领域的自动升级,突然想起2016年买的树莓派(Raspberry Pi)。那就分享一下如何入门树莓派的教程,我当时一共买了两块一款是Raspberry Pi 3b(2016年价格259元去年以抽奖…

supersu_SuperSU已从Play商店中删除,这是替代使用的方法

supersuSuperSU has long been a staple in the rooted Android community. For years, the process for getting a rooted handset was: unlock the bootloader, flash a custom recovery, install SuperSU. That’s just how it was. 长期以来,SuperSU一直是扎根于…

Oracle 11g DRCP连接方式——基本原理

学习Oracle是一个复杂、繁琐的过程。在浩如烟海的Oracle官方资料、新特性、MOS资料和各种Internal知识面前,我们总是觉得力不从心、不知所措。但是,这往往也就是我们不断坚持、积累和追寻的乐趣。  在Oracle 11g中,提出了突破传统专用/共享…

django项目开发1:搭建虚拟环境

需求 不同项目依赖不同模块版本,不能共用一套环境,虚拟环境。在系统的python环境安装 安装 pip3 install virtualenv pip3 install virtualenvwrapper-win环境变量 # 配置环境变量: # 控制面板 > 系统和安全 > 系统 > 高级系统设…

IPC之——消息队列

消息队列作用&#xff1a; 可以用于两个没有联系的进程间通信&#xff0c;创建一个消息队列类似于打开了一个文件&#xff0c;两个不同的进程都可以进行操作 消息队列之函数介绍&#xff1a; 头文件&#xff1a;<sys/type.h> <sys/ipc.h> <sys/msg.h> 1.msgg…

【招聘(上海)】To B数字化营销公司-市场易,直招.NET后端研发工程师

【招聘背景】公司&#xff1a;上海光潾网络科技有限公司成立于2016年&#xff0c;系上海市高新技术企业&#xff0c;2021年获数千万A轮融资项目&#xff1a;公司自主研发营销自动化SaaS平台- 市场易 (Custouch) &#xff0c;通过数字手段为B2B营销赋能&#xff0c;现服务100多家…

div 包裹_如何查看到达之前收到的包裹和邮件

div 包裹The United States Postal Service, UPS, and FedEx all offer online dashboards where you can see exactly what packages (and letters, in the case of the US Postal Service) are scheduled to arrive at your address. They’ll even email and send you text …

py文件的运行

安装过程及配置 安装过程准备&#xff1a; 下载好Python的安装程序后&#xff0c;开始安装&#xff0c;在进入安装界面后一定确保勾选将Python加入到系统环境变量的路径里。如图所示&#xff1a; 2如果没有选取&#xff0c;那么按照下面的步骤进行操作。在桌面上用鼠标右键点击…

加州大学信息科学院长:数据科学课程不只是工程师才修的

一般在考虑围绕数据科学的基础教育时&#xff0c;传统上的重点仍停留在计算和工程等硬性技能上。不过&#xff0c;在周四于纽约市召开的GigaOm结构数据&#xff08;Structure Data&#xff09;会议上&#xff0c;美国加州大学伯克利分校信息科学院长AnnaLee Saxenian教授表示&a…

查看安装软件/Select-object/Where-Object xxx -like

查看已安装软件 1.通过注册列表查看 $Path(HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*,HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*,HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*,HKCU:\SOFTWARE\WOW6432…