一、多继承出现的问题(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. pytorch入门2.1构建回归模型初体验(模型构建)

    pytorch入门2.x构建回归模型系列: pytorch入门2.0构建回归模型初体验(数据生成) pytorch入门2.1构建回归模型初体验(模型构建) pytorch入门2.2构建回归模型初体验( ...

  2. 组态与非组态结合的LT

    概述 最新的应用软件快速搭建平台现已投入使用.首先对名称进行规范统一一下. 英文全称:LARKIN-CN.TOP : 中文全称:拉图: 简称:LT. 特点: 组态软件开发的快速.灵活 C端软件的控件交 ...

  3. openshift v1.5 不能登录system:admin 问题

    这个好像是无法解决的,我按照github和google所有步骤试过了,还是不能登录system:admin .需要密码.弄了两个小时,后来放弃了,直接使用新版本3.6的,按照官网方法部署,可以使用直接 ...

  4. [转] 允许root通过ssh远程登录

    点击阅读原文 在Ubuntu中允许root远程访问 如果使用如xshell等远程工具首次通过root连接Ubuntu会提示拒绝访问,并不是密码不正确,而是Ubuntu默认禁止以root远程连接. 我们 ...

  5. MongoDB 基础知识学习笔记

    注意:本文假设您已经安装好 MongoDB 数据库并启动它了. 连接 MongoDB.数据库操作.集合操作 连接 MongoDB mongo ip:port/dbName -u username -p ...

  6. matlab-整数规划(非线性规划之蒙特卡洛法(随机取样法))

    首先编写M 文件mengte.m 定义目标函数f 和约束向量函数g,程序如下:function [f,g]=mengte(x);%定义目标函数f和约束向量函数g f=x()^+x()^+*x()^+* ...

  7. 2019-02-15 python接口图灵机器人(简单好玩)

    import requests import json def Run(text): url = "http://openapi.tuling123.com/openapi/api/v2&q ...

  8. 设计模式系列之组合模式(Composite Pattern)——树形结构的处理

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  9. 详述@Responsebody和HTTP异步请求的关系

    Map.ModelAndView.User.List等对象都可以作为返回值.上述这两种对象都可以使用此注解.使用此注解即表示是在同一次请求的响应体里返回.浏览器以异步http的方式来接收.比如后端的M ...

  10. SpringMVC中Map、Model、ModelMap、ModelAndView之间的关系及区别

    首先,在了解这三者之前,需要知道一点:SpringMVC在调用方法前会创建一个隐含的数据模型(Model),作为模型数据的存储容器, 成为”隐含模型”. 如果controller方法的参数为Moedl ...