21天Python第五章笔记和代码

定义类

本节目标
  1. 了解类与对象
  2. 掌握定义类的语法
  3. 理解Python的动态性
  4. 例方法
类和对象
  • 两个重要概念:类(class)和对象(object,也被称为实例,instance)
  • 类是某一批对象的抽象,可以把类理解成某种概念
  • 对象才是一个具体存在的东西
语法
  • class类名:
    • 执行语句…
    • 零个到多个类变量…
    • 零个到多个方法…
语法说明
  • 类体中的执行语句,会在定义类时自动执行
  • 如果类体中没有任何代码,使用pass语句作为占位符
Python是动态语言(1)
  • Python类的类变量可以动态增加或删除:程序在类体为新变量赋 值就是增加类变量
  • 程序也可在任何地方为已有的类增加变量
  • 也可通过del语句删除已有类的类变量
Python是动态语言(2)
  • Python对象的实例变量也动态增加或删除:程序对新实例变量赋 值就是增加实例变量,
  • 程序可以在任意地方为已有对象增加实例变量
  • 也可通过del语句删除已有对象的实例变量
实例方法
  • 函数中定义的方法,默认是实例方法
  • 实例方法第一个参数会被自动绑定到方法的调用者(该类的实例)—— 因此这些实例方法至少应该定义一个参数,该参数通常会被命名为self。

创建对象和使用对象

本节目标
  1. 构造方法
  2. 创建对象
  3. 操作实例变量
  4. 操作方法
构造方法
  • 造方法是一个特殊的实例方法,方法名为 _init_
  • 创建对象时,自动调用构造方法
  • 如果开发者没有为该类定义任何构造方法,那么Python会自动为 该类定义一个只包含一个self参数的、默认的构造方法
类的作用
  • 创建对象
  • 派生子类
创建对象
  • 调用构造器创建对象
  • 对象的作用:
    • 操作对象的实例变量(包括访问实例变量的值、添加实例变量、删除实例变量)。
    • 操作对象的方法(包括调用方法,添加方法,删除方法)。
操作对象的实例变量
  • 问实例变量的值
  • 改变:对已有的实例变量赋值
  • 增加:对不存在的实例变量赋值
  • 删除:用del语句
操作对象的实例方法
  • 调用方法
  • 改变:对已有的方法赋值
  • 增加:对不存在的方法赋值
  • 删除:用del语句
增加方法
  • 动态增加的方法,Python不会自动将方法调用者绑定到它们的第一个参数
  • 如果动态增加的方法也能自动绑定第一个参数,可借助于types模块下的MethodType进行包装
方法与实例变量总结
  • Python的方法与实例变量是统一的:它们都是对象的成员。
  • 取决于你对它所赋的值:
  • 如果所赋的值是普通值,则是实例变量
  • 如果所赋的值是函数,则是方法

实例方法与自动绑定self及使用类调用实例方法

本节目标
  1. 实例方法与自动绑定
  2. 返回self
  3. 类调用实例方法
实例方法与自动绑定
  • 使用对象调用实例方法时,Python会自动绑定方法的第一个参数(通常建议将该参数命名为self)
  • 根据第一个参数出现位置的不同,第一个参数所绑定的对象 略有区别。
    • 在构造方法中引用该构造方法正在初始化的对象。
    • 在普通实例方法中引用调用该方法的对象。
self不可省略
  • Python的一个方法调用另一个方法时,不可以省略self。
  • Python的类、对象有点类似于一个命名空间,因此在调用类、对 象的方法时,一定要加上“类.”或“对象.”的形式。
方法返回self
  • self参数可当成实例方法的返回值
  • 把self参数作为返回值,则何多次连续调用方法(只要该方法也返回self)
类调用实例方法
  • 使用类调用实例方法时,Python不会绑定方法的第一个参数
  • 如果实例方法定义了一个self参数,使用类调用实例方法时,必须 手动传入参数值

类方法与静态方法

本节目标
  1. 类方法与静态方法
  2. 类方法的参数与自动绑定
  3. 静态方法
类方法与静态方法
  • 类方法和静态方法有点相似, 它们都推荐使用类来调用(其实也可使用对象来调用)。
类方法
  • 定义类方法
  • 使用@classmethod修饰
  • 方法的第一个参数定义为cls,用类调用该方法时该参数会自动绑定
方法的自动绑定
  • 用类调用类方法,第一个cls参数会自动绑定
  • 用对象调用类方法,其实就相当于用类调用类方法,因此第一个参 数同样会自动绑定到该对象的类
静态方法
  • 定义静态方法
    • 使用@staticmethod修饰
    • 对方法参数没有要求,无论如何都不会自动绑定

案例实操:函数装饰器应用

本节目标
  1. 函数装饰器广泛应用
  2. 函数装饰器的定义和使用
  3. 函数装饰器的本质
函数装饰器的广泛应用
  • @staticmethod和@classmethod的本质就是函数装饰器,
  • staticmethod和classmethod都是Python内置的函数 。
函数装饰器的用法
  • 使用@符号引用已有的函数(比如@staticmethod、@classmethod)后,可用于修饰其他函数
函数装饰器的本质
  • 当程序使用〃@函数〃(比如函数A)装饰另一个函数(比如函数B)时,实际上完成如下两步:
  • (1)将被修饰的函数(函数B)作为参数传给@符号引用的函数(函数 A)。
  • (2)将函数B替换(装饰)成第1步的返回值。
函数装饰器与AOP
  • 通过使用函数装饰器,可在被被修饰函数之前、之后、抛出异常后增加某种处理逻辑的方式,就是其他编程语言中的AOP (Aspect Orient Programming,面向切面编程)。

类变量和实例变量

本节目标
  1. 类变量与实例变量的区分
  2. 类调用类变量
  3. 对象调用实例变量、类变量
  4. 合成属性(实例变量)
类变量与实例变量
  • 类变量:在类空间或通过类引用赋值的变量
  • 实例变量:通过对象引用或self引用赋值的变量
类、对象可访问类变量
  • 通过类,可获取、修改类变量的值
  • 通过对象,可获取类变量的值
  • 如果尝试通过对象对“类变量”赋值,就变成了新增实例变量
类不能访问实例变量
  • 实例变量不在类空间下,类不能访问实例变量
使用property合成属性
  • 使用property合成属性(相当于实例变量):
  • property(fget=None,fset=None,fdel=None,doc=None)
  • 使用property()函数定义属性时也可根据需要只传入少量参数。如合成只读属性就无需设置fget参数
使用@property装饰器
  • 还可使用@property装饰器来修饰getter方法,使之成为属性。
  • 如果需要为属性配备setter方法,则用@属性名。setter装饰器修饰setter方法

隐藏与封装

本节目标
  1. 理解封装
  2. Python的隐藏方式
  3. 合理封闭的方式
  4. Python隐藏的本质
封装
  • 封装:
    • 合理隐臟
    • 合理暴露
Python的隐藏机制
  • 规定:只要将命名为以双下画线开头的,Python就会把它们隐藏起来。
封装
  • 将实例变量、工具方法命名为以双下画线开头,这就实现了隐藏
  • 提供方法(默认暴露)来操作实例变量
双下画线的本质
  • 双下画线只是Python的一个小技巧:Python会"偷偷"地改变以双 下画线开头的成员名,会在这些成员名前添加单下画线和类名
  • 程序可通过这种方式来调用“被隐藏”的成员————一般不建议这么干
隐藏机制的总结
  • Python并未提供真正的隐藏机制,Python类中所有成员默认都是公开的;
  • 若需要隐藏某些成员,将它们命名为以双下画线开头即可。其实也 依然可通过添加“下画线加类名”前缀来调用被隐藏的成员。

继承与多继承及重写父类方法

本节目标
  1. 继承语法
  2. 继承机制 - 复用父类方法
  3. 多继承
  4. 重写父类方法
继承语法
  • 将多个父类放在子类之后的圆括号里。语法格式如下:
  • class SubClass(SuperClass1,SuperClass2,…):
  • #类定义部分
    • 从子类的角度来看,子类扩展(extend)了父类;但从父类的角度来 看,父类派生(derive)出子类。
继承=复用
  • 子类继承父类,即可获得父类的方法,这样子类即可复用父类的方法
多继承
  • Python支持多继承。
  • 但如果不是很有必要,则尽量不要使用多继承,而是使用单继承
多个父类中方法重名
  • 如果多个父类中包含了同名的方法,排在前面的父类中的方法会"遮蔽"排在后面的父类中的同名方法。
重写父类方法
  • 子类重新定义与父类 法同名的方法,称为:重写父类方法

调用被重写方法和调用父类构造方法

本节目标
  1. 调用父类被重写的方法參
  2. 使用未绑定方法调用父类构造方法
  3. 使用super()函数调用父类构造方
调用被重写的方法
  • 使用未绑定方法:以父类类名调用被重写方法,将self作为第一个参 数传入
class Employee:
    def work (self):
        print('执行996的工作时间,工作很努力')

class Manager (Employee):
    def work (self):
        print('经理工作更加拼命')

    def relax (self):
        print('经理正在休闲放松中')
        # 默认情况下,直接调用work方法,总是调用子类重写之后的方法
        # self.work()
        # 如果此处希望调用父类的方法,可通过未绑定方法来调用
        # 类名调用方法:未绑定方法,因此需要显式传入第一个参数
        Employee.work(self)

mg = Manager()
mg.relax()			
为何要调用父类构造方法

当子类提供自己的构造方法时,子类构造方法需要调用父类的构造方法

class Employee:
    def __init__ (self, salary):
        self.salary = salary * 1.8

class Manager (Employee):
    def __init__ (self, salary, title):
        # 当子类的初始化操作与父类初始化操作相同时
        # 程序不应该直接复制父类初始化代码---这样不利于后期的项目升级
        
        # 因此,子类构造器应该直接调用父类的构造方法
        self.salary = salary * 2.1
        self.title = title
    
mg = Manager(6800, '项目经理')
print(mg.salary)
print(mg.title)
调用父类构造方法(1)
  • 使用未绑定方法:既然构造方法也是实例方法,当然可以通过这种方式来调用。
class Employee:
    def __init__ (self, salary):
        self.salary = salary * 1.8

class Manager (Employee):
    def __init__ (self, salary, title):
        # 当子类的初始化操作与父类初始化操作相同时
        # 程序不应该直接复制父类初始化代码---这样不利于后期的项目升级
        
        # 因此,子类构造器应该直接调用父类的构造方法
        # self.salary = salary * 2.1

        # 方法一:使用未绑定方法调用父类构造方法:需要显式传入self参数
        Employee.__init__(self, salary)
        self.title = title
    
mg = Manager(6800, '项目经理')
print(mg.salary)
print(mg.title)
调用父类构造方法(2)
  • 使用super()函数调用父类的构造方法。
class Employee:
    def __init__ (self, salary):
        self.salary = salary * 2.3

class Manager (Employee):
    def __init__ (self, salary, title):
        # 当子类的初始化操作与父类初始化操作相同时
        # 程序不应该直接复制父类初始化代码---这样不利于后期的项目升级
        
        # 因此,子类构造器应该直接调用父类的构造方法
        # self.salary = salary * 2.1

        # 方法二:用super()函数来调用父类构造器方法:无需要传入self参数
        super().__init__(salary)
        self.title = title
    
mg = Manager(6800, '项目经理')
print(mg.salary)
print(mg.title)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值