疫情环境下的网络学习笔记 python 4.10

4.10

昨日回顾

  1. 继承

    • 优点:字类可以同时继承多个父类,解决类与类间代码冗余
    • 缺点:耦合

    python支持多继承

    • 优点:最大程度重用父类的属性
    • 缺点:违背人的思维习惯,代码可读性变差,可能触发菱形问题
  2. MIxins

    一个机制,编程的规范,通过一种命名的方式来达到提示性的效果,本质用的还是多继承,但是提升了程序的可读性

  3. 属性查找

    • 原理:每定义一个类,python都会计算出类的MRO列表 A.mro() ,以mro列表为顺序,一层层找
    • 经典类,新式类:python3自动给所有类自动继承object,所以都是新式类
    • 如果没有菱形继承,则两种类查找方式一样,若菱形继承,则分深度优先和广度优先
  4. property装饰器

    在类中的方法加上property,把方法的函数属性变成数据属性,直接调用得到数据,而不是加括号调用

    • property.setter,property.deleter

      为外部使用者提供查改删的接口,每一个函数名必须一样

    • name = property(查看,修改,删除)

    • setter,必须加 __ 是配套使用的,不然会报错递归

  5. 派生:子类衍生出的新属性

    1. 子类独有,父类没有
    2. 子类有,父类也有,则以子类为准,完全覆盖父类
    3. 子类有,父类也有,子类是在父类的基础上进行扩展

    问题:在子类派生的新方法中如何重用父类的功能

    class A:
    	def f1(self):
    		pass
        
    class B(A):
        def f1(self):
            A.f1(self)
            # 指名道姓
    

今日内容

  1. 多继承的正确打开方式:Mixins机制
  2. 在子类派生的新方法中如何重用父类的功能
    • 指名道姓调用父类下的函数,这种方法与继承无关
    • super() 得到一个特殊的对象,专门用来访问父类下的属性,严格依赖继承
  3. 多态与鸭子类型
  4. 绑定方法与非绑定方法
    • classmethod:类方法
    • staticmethod:静态方法

正课

Mixins 机制

在多继承背景下尽可能地提升多继承的可读性,让多继承满足人的思维习惯

例:汽车,直升机,民航飞机都是交通工具,都继承 “交通工具类”,但是同时直升机,民航飞机又属于飞行器,飞行器的功能不应该放在交通工具,所以应该另外设一个父类放飞行器的功能,于是直升机民航飞机继承两个类,交通工具和飞行器

在用于混入功能的类后面加上后缀名 Mixins ,一看就知道这个类只是作为功能添加到子类中,而不是作为父类

没有加Mixins后缀的类才是真爹,加了Mixin的只是额外的功能

使用时注意:

  1. 必须表示某一种功能,而不是某个物品
  2. 一个Mixin只放一种类型的功能

super()

严格依赖继承,从mro中第二位开始找方法

class OldboyPeople:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def f1(self):
        print(self.name)
        
class Teacher(OldboyPeople):
    def __init__(self,name,age,level):
        OldboyPeople.__init__(self,name,age)
        self.level = level
# 不依赖继承,指名道姓使用OldboyPeople中的init

# 依赖继承:super
class OldboyPeople:
    def __init__(self,name,age):
        self.name = name
        self.age = age
    def f1(self):
        print(self.name)
        
class Teacher(OldboyPeople):
    def __init__(self,name,age,level):
        # super(当前类,对象) 得到一个特殊的对象,该对象会参照当前类的MRO第二个位置开始,去当前类的父类中找属性,只能用在新式类
        super().__init__(name,age)
        # python3中优化,super里面不用放参数,自动会传参
        # 于是这里相当于OldboyPeople.__init__
        self.level = level
        

使用指名道姓方法和super都可以用于重用父类的属性,不过推荐使用super(),不要混用

多态

指的是同一种事物的多种形态

比如,同时动物,有多种不同的动物,但都具有一样的功能:发声

class Animal: #同一类事物:动物
    def talk(self):
        print('叫')
class Cat(Animal): #动物的形态之一:猫
    def talk(self):
        print('喵喵喵')
class Dog(Animal): #动物的形态之二:狗
    def talk(self):
        print('汪汪汪')
class Pig(Animal): #动物的形态之三:猪
    def talk(self):
        print('哼哼哼')

多态性:可以在不用考虑对象具体类型的情况下而直接使用对象

只要确定是Animal,都可以执行talk功能,而不用去理会它具体是什么类,使用者只需要了解父类的方法就可以

有了多态以后,可以定义同一的接口,接收对象,统一所有对象的使用方法

python中原本就有多态的概念 len(item)不同的类型都有相同的方法 __len__() 所以所有的数据类型都可以使用len() 函数

但其实我们完全可以不依赖于继承,只需要制造出外观和行为相同的对象,同样可以实现不考虑对象类型而使用对象。也就是所有的动物类都不继承Animal,但是他们都有talk方法,我们也能实现使用一样的方法去用每一个对象的功能

Linux系统中,一切皆文件:所有对象都有 read,write功能,那么就可以使用统一的方法,操作所有对象。

如果一定要用父类,可以使用抽象基类,强制子类使用规范的方法

import abc
class Animal(metaclass=abc.ABCMeta): # 统一所有子类的标准
    @abc.abstractmethod
    def say(self):
        pass
    # 加上这个装饰器,就是给子类统一标准,其子类必须有一个方法say,否则就报错
    # 使用这个方法后,不能实例化Animal,否则报错

class Pig(Animal):
    def say1(self):
        pass
        # 必须要有say方法,没有的化实例化的时候直接报错

绑定方法

绑定方法:将调用者本身当作第一个参数自动传入

  1. 绑定给对象的方法:调用者是对象,自动传入对象本身
  2. 绑定给类的方法:调用者是类,传入类本身

在类中的方法上面,加装饰器 @classmethod ,将下面的函数装饰成绑定给类的方法,自动传进类。

大多数场景下都是用来创造对象,提供一种新的初始化对象的方式

class Mysql:
    def __init__(self,ip,port):
        self.ip=ip
        self.port=port

    def func(self):
        print('%s:%s' %(self.ip,self.port))

    @classmethod
    def from_conf(cls):
        # 约定俗成绑定是类的,名字是cls
        return cls(settings.IP, settings.PORT)
    # 用于在配置文件中引入参数,用于初始化对象

# obj1=Mysql('1.1.1.1','11')

obj2=Mysql.from_conf()
# 调用类方法,自动将类MySQL当作第一个参数传给cls
print(obj2.__dict__)

非绑定方法

当一个函数不依赖于对象,也不依赖于类,但是还是想把他放在class里面,可以把他定义成一个静态方法,如

class A:
	def f1():  # 没有绑定任何对象或类
		print('f1')

为类中某个函数加上装饰器@staticmethod后,该方法不与类或对象绑定,类与对象都可以来调用它,但它就是一个普通函数而已,因而不会自动传值,打印类.静态方法对象.静态方法 ,都是一个函数

不代表静态方法都是无参函数,静态函数里有几个形参还是要像普通函数一样传几个参数

用法,在初始化对象的时候造uuid

def __init__(self):
self.uuid = self.uid()

@staticmethod
def uid()
	import uuid
	...

内置函数

abs()
all(iterale) # 取出所有的值进行布尔运算,有一个假就输出假,如果放进去的是一个空的可迭代对象,返回true
any(iterable)  # 但凡有一个为真,返回真。若iterable为空,返回假
bin(11) # 十进制转二进制
oct(22) # 十进制转16进制
callable() # 看对象是否可以调用
chr()
ord() # ascii和数字互转
delattr()
setattr()
#...# 下周讲
frozenset()

# 要掌握的:
dir(obj) # 查看所有属性
divmod()
enumerate(iterable) # 循环的时候即拿到索引,又拿到索引对应的值
eval('dict') # 执行字符串中的表达式
isinstance(obj,str)  # 判断一个对象是不是一个类的实例,可以用来判断类型
# 以后不用type来判断类型,用isinstance
zip() # 拉链
posted @ 2020-04-12 19:26  黑猫警长紧张  阅读(155)  评论(0编辑  收藏  举报