跳转至

Python Basics - 面对对象

基本概念

OOP

  • Object Oriented Programming

面对过程 - 怎么做

面对对象 - 谁来做?

类和对象

  • 特征属性
  • 行为方法

对象

  • 由类创建出来的具体存在
    • 属性
    • 方法

类的设计

  • 类名

    • 大驼峰命名法
    • 整个业务流程的名词提炼
  • 属性和方法的确定

基础语法

dir()内置函数

  • dir(class_name)
  • __new__() : 创建对象时,会被 自动 调用
  • __init__(): 对象被初始化时,会被 自动 调用
  • __del__(): 对象被从内存中销毁前,会被 自动 调用
  • __str__(): 返回对象的描述信息,print 函数输出使用

定义简单类(仅方法)

  • 引用

    • 类名记录对象在内存中的地址

方法中的 self参数

  • 直接添加属性:class.name = xxxx

    • 不推荐
  • 使用self在方法内部添加:self.name

    • 由那个对象调用的方法,方法内的self就是那个对象的引用。

初始化方法

  • 设置对象属性,并设置初始值

内置方法和属性

  • __del__()
  • 对象从内存中销毁前,自动调用

    • 对象的生命周期
    • del name

    • del 关键字删除一个对象

  • __str__()

  • 返回对象的描述信息,print 函数输出使用

封装案例

身份运算符

  • 比较两个对象内存地址是否一致,是否是对同一个对象的引用
  • is
  • 两标识符是否引用同一对象

  • is not

  • 两标识符是否引用不同对象

  • is vs ==

  • is 判断引用对象(内存地址)
    • == 判断引用变量的值

私有属性和私有方法

应用场景

  • 对象某些属性或方法只希望在对象内部被使用,不希望在外部被访问到

定义方式

  • __age
  • def __secret(self):

伪私有

  • Python没有真正意义的私有
  • 仅对名称做特殊处理

    • _类名 => _类名__名称

继承

单继承

  • 语法

    • class 类名(父类名):
  • 专业术语

    • 子类,父类,派生类,基类,继承,派生
  • 继承传递性

  • 方法重写

    • 覆盖父类方法

      • 子类定义和父类同名的方法
    • 对父类方法进行扩展

      • 重写父类方法
      • 需要时调用父类方法执行:super().父类方法
      • 编写子类特有的代码实现
  • 父类的私有属性和私有方法

    • 子类对象不能直接访问
    • 可通过父类父类公有方法间接访问

多继承

  • 内置属性 mro 查看方法搜索顺序

    • method resolution order
    • 依次从左到右搜索
  • 新式类

    • class Name(object)

多态

类属性和类方法

类结构

  • 创建对象两步走

    • 内存中为对象分配空间
    • 调用初始化方法为对象初始化
  • 实例化对象

    • 实例属性
    • 实例方法
  • 每个对象都有各自独立的内存空间,保存各自属性

  • 多个对象的方法在内存中只有一份,调用时需要把对象的引用传递到方法内部(self)
  • 类对象

    • Python一切皆对象
    • 类对象在内存中只有一份,可创建诸多实例对象
    • 类属性

      • 类名.类属性
    • 类方法

      • 类名.类方法(cls)
  • 调用区分

    • 类名.属性

      • 访问类属性
    • 类名.方法(cls)

      • 访问类方法,务必传入 cls
    • 类名()

      • 创建匿名实例对象:分配空间并初始化
    • 对象名.方法名(self)

      • 调用实力方法,务必传入self

类属性和实例属性

  • 类属性是类对象中定义的属性,记录类相关的特征

属性获取机制

  • 向上查找机制:自身类 -> 类对象
  • 使用赋值语句 对象.类属性 = 值,会给对象添加一个属性,而不会影响类属性的值

类方法

  • 针对类对象定义的方法
  • 语法
@classmethod
def 类方法名(cls):
    pass
  • 方法内部访问

    • cls.访问类的属性
    • cls.调用其他类方法
  • 调用

    • 类名.调用类方法
    • 不需要传递cls参数

静态方法

  • 定义

    • 既 不需要访问实例属性或调用实例方法
    • 也 不需要访问类属性或调用类方法
  • 语法

@staticmethod
def 静态方法名():
  pass

单例

单例设计模式

  • 设计模式

    • 前人工作的总结和提炼

__new__()

  • class() 创建对象时,解释器首先会调用该方法为对象分配空间
  • object基类的内置静态方法

    • 在内存中为对象分配空间
    • 返回对象的引用
  • 解释器获取对象引用后,将引用作为第一个参数,传递给__init__()

实现

  • 定义类属性isinstance, 初始值为None

    • 记录单例对象的引用
  • 重写 __new__()

    • cls.isinstance is None
    • 调用父类方法分配空间,并接收记录父类返回的引用

      • cls.isinstance = super().__new__(cls)
    • 返回该对象的引用 return cls.isinstance

  • 增加需求:仅执行一次初始化

      1. 定义类属性 init_flag, 初始为Fales

      2. 标记是否执行过初始化动作

      1. 改写 __init__()

      2. not cls.init_flag

      3. 初始化

        • cls.init_flag = True

异常

概念

  • 解释器遇到错误,停止执行并提示错误信息的情况
  • 抛出异常

    • 程序停止并提示错误信息的动作

捕获异常

  • 通用捕获

    • try ... except:...
  • 类型捕获

  • 未知错误捕获

    • except Exception as result:
  • 完整语法

    • python try: # 尝试执行的代码 pass except 错误类型1: # 针对错误类型1,对应的代码处理 pass except 错误类型2: # 针对错误类型2,对应的代码处理 pass except (错误类型3, 错误类型4): # 针对错误类型3 和 4,对应的代码处理 pass except Exception as result: # 打印错误信息 print(result) else: # 没有异常才会执行的代码 pass finally: # 无论是否有异常,都会执行的代码 print("无论是否有异常,都会执行的代码")

异常传递

  • 函数/方法异常

    • 传递给调用方
  • 截止到主程序,仍无异常处理

    • 程序终止

抛出异常(raise)

  • 依据业务需求主动抛出异常
  • 自定义异常

    • 应用Exception 异常类
      1. 创建Exception对象
      1. 使用raise关键字抛出异常

模块和包

模块

  • 概念

    • 一文件即是一模块
    • 同是一个标识符
  • 导入方式

    • import ...
    • from .. import ...
  • 模块搜索顺序

    • 先当前目录,再系统目录
    • 给文件起名时,不要和系统模块文件重名
    • 模块内置属性__file__,可以查看模块完整路径
  • 原则:每个文件都应该可以被导入

    • __name__
    • 被导入时,为模块名
      • 当前执行程序,为__main__

包(Package)

  • 概念

    • 包含多个模块的特殊目录
    • 具有特殊文件:init.py
    • 命名同变量名

发布模块

制作发布压缩包步骤

  1. 创建 setup.py
from distutils.core import setup

setup(name="hm_message",  # 包名
      version="1.0",  # 版本
      description="itheima's 发送和接收消息模块",  # 描述信息
      long_description="完整的发送和接收消息模块",  # 完整描述信息
      author="itheima",  # 作者
      author_email="itheima@itheima.com",  # 作者邮箱
      url="www.itheima.com",  # 主页
      py_modules=["hm_message.send_message",
                  "hm_message.receive_message"])
python3 setup.py build
  1. 生成发布压缩包
python3 setup.py md_name

安装模块

tar -zxvf module_name_1.0.tar.gz
sudo python3 setup.py install

卸载模块

  • 将安装模块的目录删除即可
    cd /usr/local/lib/python3.6/dist-package/
    sudo rm -r module_name
    

pip 安装第三方模块

文件

概念

  • 概念

    • 数据
  • 作用

    • 存储
  • 存储方式

    • 文本文件

      • 本质还是二进制
    • 二进制文件

基本操作

  • 固定三步

    • 打开文件
    • 读写文件
    • 关闭文件
  • 函数/方法

    • open()

      • 返回文件对象
    • read()

      • 操作文件对象
    • write()

      • 操作文件对象
    • close()

      • 操作文件对象
  • 读取文件read()

    • 一次性读入并返回所有内容
    • 结束后,文件指针移动到文件末尾
  • 打开文件open()

  • 默认以只读方式打开并返回文件对象

  • 格式

    f = open("文件名", "访问方式")
    
  • 访问方式

    • r 以只读方式打开文件。

      • 文件的指针将会放在文件的开头,这是默认模式。
      • 如果文件不存在,抛出异常
    • w 以只写方式打开文件。

      • 如果文件存在会被覆盖。
      • 如果文件不存在,创建新文件
    • a 以追加方式打开文件。

      • 如果该文件已存在,文件指针将会放在文件的结尾。
      • 如果文件不存在,创建新文件进行写入
    • r+ 以读写方式打开文件。

      • 文件的指针将会放在文件的开头。
      • 如果文件不存在,抛出异常
    • w+ 以读写方式打开文件。

      • 文件存在会被覆盖。
      • 文件不存在,创建新文件
    • a+ 以读写方式打开文件。

      • 如果该文件已存在,文件指针将会放在文件的结尾。
      • 如果文件不存在,创建新文件进行写入
  • 按行读取文件内容

  • readline()

    # 打开文件
    file = open("README")
    while True:
        # 读取一行内容
        text = file.readline()
    
        # 判断是否读到内容
        if not text:
            break
    
        # 每读取一行的末尾已经有了一个 `\n`
        print(text, end="")
    
    # 关闭文件
    file.close()
    

文件/目录的管理

  • 文件操作

    • rename 重命名文件 os.rename(源文件名, 目标文件名)
    • remove 删除文件 os.remove(文件名)
  • 目录操作

    • listdir 目录列表 os.listdir(目录名)
    • 02 mkdir 创建目录 os.mkdir(目录名)
    • 03 rmdir 删除目录 os.rmdir(目录名)
    • 04 getcwd 获取当前目录 os.getcwd()
    • 05 chdir 修改工作目录 os.chdir(目标目录)
    • 06 path.isdir 判断是否是文件 os.path.isdir(文件路径)

文件文本编码格式

  • ASCII

    • 256个
    • 0 - 127
  • utf-8

  • Python2 使用中文
# *-* coding:utf8 *-*
# coding=utf-8
  • unicode

eval函数