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 核心…

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包以及语言包,并添加到项目中。添加到项目的方法,参考了这篇…

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一直是扎根于…

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

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

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文件的运行

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

网络编程基础(一)

一.楔子 你现在已经学会了写python代码,假如你写了两个python文件a.py和b.py,分别去运行,你就会发现,这两个python的文件分别运行的很好。但是如果这两个程序之间想要传递一个数据,你要怎么做呢? 这个问题以…

dotnet-exec 让 C# 程序更简单

dotnet-exec 让 C# 程序更简单Introdotnet-exec是一个可以执行 C# 程序而不需要项目文件的命令行工具,并且你可以指定自定义的入口方法不仅仅是Main方法在 python/NodeJs 里,可以使用python xx.py/node xx.js来运行代码,在 C# 中一般是需要项…

office数据集dslr_如何将照片从DSLR无线传输到智能手机

office数据集dslrYou’ve got a great digital camera. You’ve got all your social media apps on your phone. Wouldn’t it be nice if you could snap a beautiful shot with your DSLR and shuttle it right over to your phone to throw up on Facebook or Instagram? …

文件管理、命令别名和glob

一、复制命令:cp src dest1.如果scr是文件a.如果dest不存在,则新建dest并将src的内容填充到dest里b.如果dest存在,则会用src里的内容覆盖dest里的内容,即覆盖dest2.如果src是目录a.如果dest不存在,则新建dest,然后把src下的内容复…

django版本区别/与版本匹配

一、区别 路由层 1.django 1.x路由层使用url方法 django 2.x和3.x版本使用path方法 url() 第一个参数支持正则 path()第一个参数是不支持正则的 可以使用 re_path替代url() from django.urls import re_path # django2.0中的re_path #不建议导入url,不能区分版本 #from djang…

中兴面试一个星期没有回音_如何在没有回声的情况下从亚马逊获取即时时尚建议...

中兴面试一个星期没有回音The Echo Look is a new device from Amazon that’s able to take a look at your outfits and tell you which one looks the best on you. However, you actually don’t need the Echo Look to get this kind of instant fashion advice from Amaz…

table分页的简单实现逻辑

为什么80%的码农都做不了架构师&#xff1f;>>> //table分页函数showPageNum: function(pageNum, allPageNum) { //pageNum点击第几页&#xff0c;allPageNum总页数$(".c_page .c_page_list").children().remove();for(var i1;i<allPageNum;i){var p…