一、多继承出现的问题(mixins机制)

继承从人的思维逻辑上看,就是什么什么(子类)是什么(父类),具体一点就是人类和狗类都属于动物类。

但是如果有特殊情况导致出现多继承,就会违反人类的思维逻辑,一类事物是多种事物

从代码层面来讲

class Vehicle:
pass class FlyableMixin:
def fly(self):
pass class CivilAircraft(FlyableMixin,Vehicle): # 民航飞机
pass class Helicopter(FlyableMixin,Vehicle): # 直升飞机
pass class Car(Vehicle): # 汽车并不会飞,但按照上述继承关系,汽车也能飞了
pass

民航飞机和直升飞机和汽车都属于交通工具,如果我们要解决民航飞机和直升飞机的代码冗余把飞行功能提取到交通工具类中。会导致汽车也能飞,这就违反了我们设置汽车类的原则。

多继承解决了我们代码冗余问题,也没有违反汽车类的原则。

但是多继承又给我们带来新的问题,程序可读性差。

这里引入一种规范,如果我们需要为多种类去总结一类功能,我们可以定义一个特殊的功能类,以Mixin为结尾,在集成时放在唯一父类的左边。

二、派生与方法重用

子类可以派生出自己新的属性,在进行属性查找的时候,子类的属性会优先父类查找。

class People:
def __init__(self,name,age):
self.name = name
self.age = age
class Teacher(People):
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex

teacher里面的init和父类的init方法有重复的地方,我们可以通过以下两种方法实现父类方法的重用

方法一:‘指名道姓’的调用某一个类的函数

class People:
def __init__(self,name,age):
self.name = name
self.age = age
class Teacher(People):
def __init__(self,name,age,sex):
People.__init__(self,name,age)
self.sex = sex

方式二:super()

super()调用父类提供给自己的方法=》严格依赖继承关系

调用super()会得到一个特殊的对象,该对象会参照发起属性查找的那个类的mro,去当前类的父类中找属性

class Teacher(People):
def __init__(self,name,age,sex):
super().__init__(name,age)
self.sex = sex

这两种方式的区别是:方式一是跟继承没有关系的,而方式二的super()是依赖于继承的,并且即使没有直接继承关系,super()仍然会按照MRO继续往后查找

class A:
def text(self):
super().text()
class B:
def text(self):
print("text B")
class C(A,B):
pass obj = C()
obj.text()
# 此刻调用是根据类C的mro列表查找顺序查找,即便A没有继承B,根据C的继承,还是会查到B中的text >>>text B

三、多态

1 什么是多态

定义:同一种事物的多重形态

多态和继承是一种相对立的抽象概念

class Animal:
pass class People(Animal):
pass class Dog(Animal):
pass class Pig(Animal):
pass

人类,狗类,猪类,他们继承于父类动物类,说明他们都有动物类的属性。

换一种说话,动物类有三种形态,人类,猪类,狗类,这就是多态

2 为什么要有多态

多态性指的是可以在不考虑对象具体类型的情况下而直接使用对象,我们在知道了该类是哪一种类型的不同形态,我们就可以用那种类型的方法进行操作。

class Animal: # 统一所有子类的方法
def say(self):
print('动物基本的发声频率。。。',end=' ') class People(Animal):
def say(self):
super().say()
print('嘤嘤嘤嘤嘤嘤嘤') class Dog(Animal):
def say(self):
super().say()
print('汪汪汪') class Pig(Animal):
def say(self):
super().say()
print('哼哼哼')

更进一步,我们可以通过定义统一的接口,接受传入的对象

def animal_say(animal):
animal.say()
#只要是动物类所属其他多态类的对象,都可使用这个方法,不需要任何条件

综上我们得知,多态性的本质在于不同的类中定义有相同的方法名,这样我们就可以不考虑类而统一用一种方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有某些方法名

import abc

# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
def talk(self): # 抽象方法中无需实现具体的功能
pass class Cat(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准
def talk(self):
pass cat=Cat() # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化

3 python中多态的鸭子类型

鸭子类型:如果一个东西,他看起来像鸭子,叫起来也像鸭子,我们就可以把他看做鸭子

放在程序中,如果一个类,看起来像a,有a的特性,那我们就可以把它当做a来使用(可以去使用a中的方法,不管他是否继承于a)

#二者看起来都像文件,因而就可以当文件一样去用,然而它们并没有直接的关系
class Txt: #Txt类有两个与文件类型同名的方法,即read和write
def read(self):
pass
def write(self):
pass class Disk: #Disk类也有两个与文件类型同名的方法:read和write
def read(self):
pass
def write(self):
pass

四、绑定方法与非绑定方法

定义

类中定义的函数有两大类:绑定方法与非绑定方法

绑定方法也分为两类:对象的绑定方法,类的绑定方法

1 绑定方法

1.1对象的绑定方法

类中的方法都是默认绑定给对象的

class Peopel:
#say就是类中对象的绑定方法
def say(self):#self是对象绑定方法规范第一个传参写法
pass

特性

对象在使用时,作为绑定方法,会把对象作为第一个参数传入

类在调用时,作为函数,要严格按照函数的传参对应传值

1.2 类的绑定方法

为类中某个函数加上装饰器@classmethod后,该函数就绑定到了类

class Peopel:
@classmethod
#text就是类中对象的绑定方法
def text(cls):#cls是类绑定方法规范第一个传参写法
pass

特性

对象在试用时和类在使用时,都会把类作为第一个参数传入,所以这种方法对象调用没有意义,只是用来给类使用的。

2 非绑定方法

为类中某个函数加上装饰器@staticmethod后,该函数就变成了非绑定方法,也称为静态方法。该方法不与类或对象绑定,类与对象都可以来调用它,但它就是一个普通函数而已,因而没有自动传值那么一说

import uuid
class MySQL:
def __init__(self,host,port):
self.id=self.create_id()
self.host=host
self.port=port
@staticmethod
def create_id():
return uuid.uuid1()

总结

如果我们这个方法是给类用的,加上装饰器@classmethod,让这个方法自动绑定类

如果我们这个方法是给对象用的,不用管,python中类的方法默认都是绑定对象

如果我们这个方法谁都能用,加上装饰器@staticmethod,设置成静态方法谁调他都只是个普通的函数。

五、内置函数

1 zip

把传入的两个可迭代对象一一对应成元组放在字典里,多出的不管

v1='hello'
v2=[111,222,333,444,5555,6666]
res=zip(v1,v2)
print(list(res))
>>>[('h', 111), ('e', 222), ('l', 333), ('l', 444), ('o', 5555)]

2 divmod

传入的第一个值为被除数,第二个值为除数,返回一个元组,第一个值是商,第二个值是余数

print(divmod(10000,33))
>>>(303, 1)

3 dir

查看对象或者类有哪些方法

class Foo:
pass
obj=Foo()
obj.xxx=1111
print(dir(obj)) # obj.哪些属性
>>>['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'xxx']

4 enumerate

枚举,迭代循环一个可迭代对象,返回一个enumerate对象,内含可迭代对象的所在位置和值的一个一个元组

for v in enumerate(['a','b','c']):
print(v)
print(type(enumerate(['a','b','c'])))
>>>(0, 'a')
>>>(1, 'b')
>>>(2, 'c')
>>><class 'enumerate'>

5 eval

执行字符串中的表达式

res=eval('{"a":1}') # 执行字符串中的表达式
print(res,type(res))
>>>{'a': 1} <class 'dict'>

6 isinstance

判断类型和type区别使用,type是用来返回类型的

class Foo:
pass
obj=Foo()
print(isinstance(obj,Foo))
print(isinstance([],list)) # 类型判断推荐使用isinstance
print(type([]) is list) # 不推荐使用
>>>True
>>>True
>>>True

day30 继承、派生与多态,类中方法和内置函数的更多相关文章

  1. 洗礼灵魂,修炼python(36)--面向对象编程(6)—类的相关内置函数issubclass,hasattr等

    啥?我靠,类也有内置函数?哈哈,确实有的.有哪些呢?请往下看 issubclass(cls, class_or_tuple, /) 1.基本属性: 方法全是特殊方法 2.使用方法:判断一个类是否由另一 ...

  2. python 类(object)的内置函数

    python 类(object)的内置函数 # python 类(object)的内置函数 ### 首先 #### 以__双下划线开头的内置函数 __ #### __往往会在某些时候被自动调用,例如之 ...

  3. Day07:常用模块,面向对象编程(对象&类)及内置函数

    今日内容:1.常用模块2.面向对象编程(*****)    介绍面向对象编程    类    对象3.内置函数------------------------------1.面向过程编程    核心“ ...

  4. python类中的内置函数

    __init__():__init__方法在类的一个对象被建立时,马上运行.这个方法可以用来对你的对象做一些你希望的初始化.注意,这个名称的开始和结尾都是双下划线.代码例子: #!/usr/bin/p ...

  5. day29 类中的内置函数方法 __str__ __repr__ __call__ isinstance() issubclass()

    __str__()__repr__()__len__() str() 转字符串repr() 让字符原形毕露的方法len() 计算长度 内置的方法很多,但是并不是全部都在object中,比如len(), ...

  6. Day 21 python :面向对象 类的相关内置函数 /单例模式 /描述符

    1.isinstance(obj,cls) 检查obj是否是类cls的对象: 备注:用isinstance 的时候,产生实例后,会显示实例既是父类的实例,也是子类的实例 class Mom: gend ...

  7. python 类中__call__内置函数的使用

    class F: def __call__(self, *args, **kwargs): print('执行__call__') s = F()s() 先给类创建一个对象,直接通过对象来执行,就会自 ...

  8. python基础(14)-反射&类的内置函数

    反射 几个反射相关的函数可参考python基础(10)-匿名函数&内置函数中2.2.4反射相关 类的一些内置函数 __str__()&__repr__() 重写__str__()函数类 ...

  9. python面向对象的多态-类相关内置函数-类内置魔法函数-迭代器协议-上下文管理-04

    多态 一种事物具备不同的形态 例如:水 --> 固态.液态.气态 多态:# 多个不同对象可以相应同一个对象,产生不同的结果 首先强调,多态不是一种特殊的语法,而是一种状态,特性(多个不同对象可以 ...

随机推荐

  1. 让LED程序在片外SDRAM中运行

    让LED程序在片外SDRAM中运行 一.引子 在前一篇文章中,我们已经成功点亮过LED了,为什么还要再重复一次呢? 我们已经知道,Mini2440开发板有两种启动模式:从NorFlash启动和从Nan ...

  2. 消息队列——RabbitMQ的基本使用及高级特性

    文章目录 一.引言 二.基本使用 1. 简单示例 2. work queue和公平消费消息 3. 交换机 三.高级特性 1. 消息过期 2. 死信队列 3. 延迟队列 4. 优先级队列 5. 流量控制 ...

  3. 【Key】 Windows 95 到 Windows10所有KEY 包括OEM系统

    部分可能不准确,请见谅,数据源自Baidu,由noogai00整理,数据为Microsoft.所有 Windows 95 02398-OEM-0030022-5886409297-OEM-002128 ...

  4. c++运算符重及其调用

    本文参考自:https://blog.csdn.net/lisemi/article/details/93618161 运算符重载就是赋予运算符新功能,其本质是一个函数. 运算符重载时要遵循以下规则: ...

  5. CODING DevOps 系列第五课:微服务测试——微服务下展开体系化的微服务测试

    微服务测试的痛点与挑战 这张图可以形象地展示单体服务和微服务的对比,单体应用就像左边巨大的集装箱,软件模块和应用都包括其中:而微服务就像是由一个小集装箱组成,微小的服务组成一个庞大.完整的系统.单体服 ...

  6. .NETCore微服务探寻(二) - 认证与授权

    前言 一直以来对于.NETCore微服务相关的技术栈都处于一个浅尝辄止的了解阶段,在现实工作中也对于微服务也一直没有使用的业务环境,所以一直也没有整合过一个完整的基于.NETCore技术栈的微服务项目 ...

  7. 八张图彻底了解JDK8 GC调优秘籍-附PDF下载

    目录 简介 分代垃圾回收器的内存结构 JDK8中可用的GC 打印GC信息 内存调整参数 Thread配置 通用GC参数 CMS GC G1参数 总结 简介 JVM的参数有很多很多,根据我的统计JDK8 ...

  8. 人脸识别Demo解析C#

    概述 不管你注意到没有,人脸识别已经走进了生活的角角落落,钉钉已经支持人脸打卡,火车站实名认证已经增加了人脸自助验证通道,更别提各个城市建设的『智能城市』和智慧大脑了.在人脸识别业界,通常由人脸识别提 ...

  9. 计算机网络之tcp与udp的区别

    1.基于连接与无连接: 2.对系统资源的要求(TCP较多,UDP少):3.UDP程序结构较简单:4.流模式与数据报模式 :5.TCP保证数据正确性,可靠稳定,UDP可能丢包:6.TCP保证数据顺序,U ...

  10. Jmeter系列(35)- 使用 ServerAgent 监控服务器

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 前言 做性能测试,监控服务器资源指标是 ...