一、多继承出现的问题(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. ES 复合查询

    ES在查询过程中比较多遇到符合查询,既需要多个字段过滤也需要特殊情况处理,本文简单介绍几种查询组合方便快捷查询ES. bool布尔查询有一个或者多个布尔子句组成     filter 只过滤符合条件的 ...

  2. DedeCms 首页、列表页调用文章body内容的方法

    [第一种方法] arclist标签使用如下: {dede:arclist row='1' typeid='1' addfields='body' idlist='1' channelid='1'} [ ...

  3. @codechef - JADUGAR2@ Chef and Same Old Recurrence 2

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 定义 dp 序列: \[dp(1) = K\\ dp(n) = ...

  4. Codeforces Round #561 (Div. 2) A Tale of Two Lands 【二分】

    A Tale of Two Lands 题目链接(点击) The legend of the foundation of Vectorland talks of two integers xx and ...

  5. Chosen by god【组合数打表】

    Chosen by god 题目链接(点击) Everyone knows there is a computer game names "hearth stone", recen ...

  6. Linux使用手册

    一.开关机 sync :把内存中的数据写到磁盘中(关机.重启前都需先执行sync) shutdown -rnow或reboot :立刻重启 shutdown -hnow :立刻关机 shutdown ...

  7. TensorFlow从0到1之XLA加速线性代数编译器(9)

    加速线性代数器(Accelerated linear algebra,XLA)是线性代数领域的专用编译器.根据 https://www.tensorflow.org/performance/xla/, ...

  8. 授权函数-web_set_certificate_ex

    设置证书和密钥文件属性. int web_set_certificate_ex(const char * option_list,LAST); 该函数与Loadrunner 录制设置属性中的Recor ...

  9. controlfile的情景恢复

    控制文件测试 百度百科:控制文件(Control File)是Oracle的物理文件之一,它记录了数据库的名字.数据文件的位置等信息.控制文件的重要性在于,一旦控制文件损坏,数据库将会宕机.如果没有数 ...

  10. 十六进制颜色码及其表示-(6 digit color code)

    我们知道对于RGB颜色系统,颜色是由三个256位的十进制数值表示的: (R:0-255,G:0-255,B:0-255) 那么一个三元组可以确定一种颜色. 然而,在很多配置文件中颜色并不是直接用十进制 ...