Python-Base04

本文详细介绍了Python中文件操作的基本流程,包括文件的打开、读写和关闭,以及不同模式下的操作细节。同时深入探讨了面向对象编程的概念,包括类、对象、属性、方法的定义和使用,以及继承、封装、多态等核心特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


day16

文件 file
  文件是用于数据存储的单位
  文件通常用来长期存储数据
  文件中的数据是以字节为单位进场顺序存储的
  
文件的操作流程
  1.打开文件
  2.读/写文件
  3.关闭文件
  注:
    任何操作系统,一个应用程序同事打开文件的数量有最大数限制

文件的打开函数
open(file, mode='rt')
用于打开一个文件,返回此文件流对象,如果打开文件失败,则会触发OSError错误

文件的关闭方法:
F.close()     # 关闭文件,释放系统资源

示例:
# file_open.py
try:
    f = open('./myfile.txt')
    print('打开文件成功')
    s = f.read()  # 读取全部内容,形成字符串用s绑定
    print('读取到', len(s), '个字符')
    print('内容是', s)
    f.close()
except OSError:
    print('文件打开失败')

文本文件操作
  操作模式:文件操作模式要一致
    't'
  说明:
    默认文件中存储的都是为字符数据,在读写过程中会自动进行编解码操作
    文本文件以行为单位进行分隔,在python内部统一用'\n'作为换行符进行分隔
    对文本文件的读写操作需要用字符串str()进行数据操作
  各操作系统= 的换行符
    Linux 换行符 '\n'
    Widows 换行符 '\r\n'
    新Mac OS 换行符 '\n'

文件流对象是可迭代对象,迭代过程中将以换行符'\n'作为分隔符
示例:
f = open('phonenumber.txt')
for x in f:
    print(x)

标准输入输出文件
  sys.stdin     标准输入文件  # 默认键盘  ctrl+d 输入文件结束符
  sys.stdput    标准输出文件  # 默认屏幕终端
  sys.stderr    标准错误输出文件  # 默认屏幕
  模块名:sys
  注:
    标准文件不需要打开和关闭就可以使用
示例:
stdin.py
import sys
while True:
     s = sys.stdin.readline()  # 类似input
     if lens < 2:
         break
     print('刚才读到的是', len(s), '个字符')
     print('读的内容是', s)

sys.stdout.write('hello')
sys.stdout.write(' ')
sys.stdout.write('world!\n')
print('结束')

在Linux命令行中 ~$ python3 stderr.py > mystdout.txt 2> myerr.txt
>  标准输出重定向
2> 标准错误输出重定向 


二进制文件操作:
  二进制文件操作模式字符: 'b'
  默认文件中存储的是以字节为单位数据,通常有人为规定的格式
  二进制文件操作需要用字节串进行读写

F.read() / F.readline() / F.readlines() 返回类型
  对于文本文件,F.read()等函数返回为字符串(str)
  对于二进制文件,F.read()等函数返回为字节串(bytes)

F.write() 对于二进制文件也需要用字节串来操作

F.tell()  返回当前的读写位置(从文件头以字节为单位)

F.seek(偏移量, whence=相对位置)  设置读写位置
偏移量
    大于0的数代表向文件末尾方向移动的字节数
    小于0的数代表向文件头方向移动的字节数
相对位置
    0 代表从文件头开始偏移
    1 代表从文件当前读写位置开始偏移
    2 代表从文件尾开始偏移


汉字编码(讲两种)
  国标系列:
    GB18030  (二字节或四字节编码,共27533个字)
      GBK    (二字节编码,共21003个字)
        GB2312  (二字节编码,共6763个汉子)
    汉子编码一定大于 7F
    (Windows 常用)
  国际标准: UNICODE <-------> UTF-8
    (Linux / Mac OS X / IOS / Android 等常用)

python 编码字符串
    'gb2312'
    'gbk'
    'gb18030'
    'utf8'
    'ascii'
    ...
    以上字符串用于encode和decode中


编码注释:
在pyth on源文件的第一行或第二行写入如下内容:
# -*- coding:gbk -*-
# 设置源文件编码格式为gbk

# -*- coding:utf-8 -*-
# 设置源文件编码格式为utf-8
作用:
  告诉解释执行器,此文件的编码是什么


练习
1.写文件实现复制文件的功能
要求:
    1.要考虑特大文件的问题
    2.要关闭文件
    3.要能二进制文件
如:
请输入源文件路径名: /home/tarena/xxx.tar.gz
请输入目标文件路径名: ./a.tar.gz
显示:
    文件已成功复制


2.修改学生信息管理程序,加入两个功能
9)  保存信息到文件(si.txt)
10)从文件中读取数据(si.txt)
 


文本模式
    把文件的字节码自动转换为字符串
    换行符会自动转换为'\n'
二进制模式
    通过字节串(字节数组)进行读写

day17

面向过程编程:
    函数做单位

面向对象编程 Object-Oriented Programing
    对象是指现实中的物体或实体
    对象有很多属性(名词,形容词)
        eg:姓名,年龄,性别...
    对象有很多行为(动词)
        eg:学习,吃饭,睡觉,工作...
面向对象
    把一切都看成对象(或实例)用各种对象之间的关系来描述事物
什么是类:
    拥有相同属性和行为的对象分为一组,即为一个类
    类是用来描述对象的工具,用类可以创建此类的对象(实例)
面向对象示意:
    车(类) -----> BYD E5(湘A11111) 实例(对象)
           \
            \--> BMW X5(湘F22222) 实例(对象)

类的创建语句:
class 类名(继承列表):
    '类的文档字符串'
    实例方法的定义
    类变量的定义
    类方法的定义(@classmethod)
    静态方法的定义(@ststicmethod)
作用:
    创建一个类
    类用于描述对象的行为和属性
    类用于创建此类的一个或多个对象(实例)
说明:
    类名必须为标识符
    类名实质就是变量,它绑定一个类
实例见:
  myclass.py

构造函数
    构造函数的调用表达式
    语法:
    类名([创建传参列表])
    作用:
        创建这个类的实例对象,并返回此实例的引用关系
示例:
  myclass.py

实例对象说明:
    实例有自己的作用域和名字空间,可以为该类的对象添加实例变量(也叫属性)
    实例可以调用类方法和实例方法
    实例可以访问类变量和实例变量

实例方法 method
语法:
class 类名(继承列表):
    def 实例方法名(self, 参数1, 参数2,...):
        '文档字符串'
        语句
作用:
    用于描述一个对象的行为,让此类型的全部对象都拥有相同的行为
说明:
    实例方法实质是函数,是定义在类内的函数
    实例方法至少有一个形参,第一个形参代表调用这个方法的实例,一般命名为'self'
实例方法的调用语法:
实例.实例方法名(调用传参)

类名.实例方法名(实例,调用传参)
示例:
  myclass.py

实例属性 attribute(也叫实例变量)
    每个实例对象可以有自己的变量,称为实例变量(也叫属性)
语法:
    实例.属性名
赋值规则:
    首次为属性赋值则创建此属性
    再次为属性赋值则修改属性的绑定关系
作用:
    记录每个对象自身的数据
示例:
  myclass.py

删除属性 del 语句
    del 对象.实例变量名
del 语句:
    del 变量名
    del 列表[整数表达式]
    del 字典[key]
    del 对象.属性

初始化方法:
作用:
    对新创建的对象添加属性
语法:
class 类名(继承列表):
    def __init__(self [,形参列表]):
        语句块
说明:
    初始化方法比必须为'__init__'不可改变
    初始化方法会在构造函数创建实例后自动调用,且将实例自身通过第一个参数 self 传入 '__init__' 方法
    构造函数的实参将通过 __init__ 方法的参数列表传入到'__init__'方法中
    初始化方法内如果需要return 语句返回,则只能返回None
示例:
  init_method.py


析构方法:
语法:
class 类名(继承列表):
    def __del__(self):
        ...
说明:
    析构方法在对象被销毁时被自动调用
    python建议不要在对象销毁时做任何事情,因为销毁的时间难以确定

预置实例属性
__dict__ 属性
    __dict__属性绑定一个存储此实例自身变量的字典
示例:
class Dog:
    pass

dog1 = Dog()
print(dog1.__dict__)  # {}
dog1.kinds = '京巴'
print(dog1.__dict__)  # {'kinds':'京巴'}


__class__ 属性
    此属性用于绑定创建这些实例的类
作用:
    可以借助于此属性来访问创建此实例的类
示例:
class Dog:
    pass
dog1 = Dog()
print(dog1.__class__)
dog2 = dog1.__class__()
print(dog2.__class__)


用于类的函数:
isinstance(obj, class or tuple)
返回这个对象obj是否是某个类的对象或某些类中的一个类的对象,如果是则返回True,否则返回False
isinstance(123, (int, str, list))  # True
isinstance(123.0, int)  # False
type(obj)  返回对象的类型


练习
修改原来的学生信息管理程序,将原来的字典存储学生信息
先改用对象来存储学生信息
(要求类Student 要写在模块 student.py 中)


day18

类变量
    类变量是类的属性,此属性属于类,不属于此类的实例
作用:
    通常用来存储该类创建的对象的共有属性
说明:
    类变量可以通过类直接访问
    类变量可以通过类的实例直接访问
    类变量可以通过此类的对象的__class__属性间接访问
示例:
  class_variable.py

类的文档字符串
  类内第一个没有赋值给任何变量的字符串为类的文档字符串
  类的文档字符串可以用类的 __doc__ 属性访问

类的 __slots__ 列表
作用:
    限定一个类创建的实例只能有固定的属性(实例变量)
    不允许对象添加列表意外的属性(实例变量)
    防止用户因写错属性名而发生程序错误
说明:
    __slots__ 列表绑定一个字符串列表
    含有 __slots__列表的类所创建的实例对象没有__dict__属性,即此实例不用字典来存储对象的属性(实例变量)
示例:
# slots.py
class Human:
    __slots__ = ['name', 'age']  # 限制此类的对象只能有'name'和'age'属性
    def __init__(self, name, age):
        self.name = name
        self.age = age

h1 = Human('liu', 18)
print(h1.age)  # 18
# h1.Age = 19    # 出错,AttributeError
print(h1.age)  # 18
# print(h1.__dict__)   # 出错,AttributeError


类方法 @classmethod
  类方法是用于描述类的行为的方法,类方法属于类,不属于类的实例
说明:
  类方法需要使用@classmethod装饰器定义
  类方法至少有一个形参,第一个形参用于绑定类,约定写为'cls'
  类和该类的实例都可以调用类方法
  类方法不能访问此类创建的实例属性
示例:
  class_method.py


静态方法 @staticmethod
  静态方法是定义在类内部的函数,此函数作用域是类的内部
说明:
    静态方法需要使用 @staticmethod装饰器定义
    静态方法与普通函数定义相同,不需要传入self实例参数和cls参数
    静态方法只能凭借该类或类创建的实例调用
    静态方法不能访问类变量和实例变量(属性)
示例:
  static_method.py


实例方法,类方法,静态方法,函数 小结
    不想访问 类内 和 实例内 的变量,用静态方法
    只想访问 类内变量,不想访问 实例变量,用类方法
    既要访问 类变量,也想访问 实例变量 用实例方法
    函数与静态方法相同,只是静态方法的作用域定义在类内


继承 inheritance 和 派生 derived
    继承是指从已有的类中派生出新的类,新类具有原类的行为,并能扩展新的行为
    派生类就是从一个已有类中衍生称新类,在新类上可以添加新的属性和行为
作用:
    1.用继承派生机制,可以将一些共有功能加在基类中,实现代码的共享
    2.在不改变基类的代码的基础上改变原有的功能
名词:
    基类(base class) / 超类(super class) / 父类(father class)
    派生类(derived class) / 子类(child class)

单继承:
语法:
    class 类名(基类名):
        语句块
说明:
    单继承是指由一个基类衍生出的新的类
示例:
  inherit.py

继承说明:
    python3任何类都直接或间接的继承自object类
    object类是一切的超类
类的__base__属性
    __base__属性用来记录此类的基类

python内建的类详见:
>>> help(__builtins__)


覆盖 override
    覆盖是指在有继承关系的类中,子类中实现了与基类同名的方法,在子类的实例调用该方法时,实际调动的是子类中的覆盖版本,这种现象叫做覆盖
示例:
  override.py


子类对象显式调用基类(被覆盖)方法的方式:
    基类名.方法名(实例, 实际调用传参)

super 函数
    super(cls, obj) 返回绑定超类的实例(要求obj必须是cls类型的实例)
    super() 返回绑定超类的实例,等同于:super(__class__,实例方法的第一个参数),必须在方法内调用
作用:
    借助super() 返回的实例间接调用其父类的覆盖方法

显式调用基类的初始化方法
    当子类中实现了 __init__方法,基类的构造方法并不会被调用
    def __init__(self,...)
示例见:
  super_init.py

1.学生管理系统用学生对象封装
(要求,不要在外部直接操作学生的属性,操作行为用方法代替)


day19

用于类的函数
issubclass(cls, class or tuple)
    判断一个类是否继承自其他类,如果此cls 是 class or tuple 的 子类则返回true

封装 enclosure
  封装是指隐藏类的实现细节,让使用者不关心这些细节
  封装的目的是让使用者通过尽可能少的方法(或属性)操作对象

私有属性和私有方法
    python类中以双下划线(__)开头,不以双下划线结尾的标识符为私有成员,私有成员或只能用类内的方法进行访问和修改
      以__开头的实例变量是私有属性
      以__开头的方法为私有方法
示例:
  enclosure.py

多态 polymorphic
字面意思:多种状态
多态是指在有继承/派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态

状态:
    静态(编译时状态)
    动态(运行时状态)
说明:
    多态调用方法与对象相关,不与类相关
    Python的全部对象都只有'运行时状态(动态)'
    没有'C++'里的'编译时状态(静态)'
示例:
  poly.py

面向对象的语言的特征
    继承
    封装
    多态 # 同一函数 在不同对象会调用不同方法


多继承 multiple inheritance
  多继承是指一个子类继承自两个或两个以上的基类
语法:
class 类名(基类名1, 基类名2,...):
    ...
说明:
    一个子类同时继承自多个父类,父类中的方法可以同时被继承下来
    如果两个父类中有同名的方法,而在子类中又没有覆盖此方法时,调用结果难以确定

多继承的问题(缺陷)
    标识符(名字空间)冲突的问题
        要谨慎使用继承

多继承的 MRO(Method Resolution Order) 问题
  类的 __mro__ 属性
    此属性用来记录类的方法查找顺序
    super.方法 是根据 调用对象的 __mro__ 来确定调用顺的
示例:
class A:
    def go(self):
        print(1)
class B:
    def go(self):
        print(2)
        super().go()
class C:
    def go(self):
        print(3)
        super().go()
class D:
    def go(self):
        print(4)
        super().go()
d = D()
d.go()
print(d.__mro__)


函数重写
  在自定义类内添加相应的方法,让自定义类创建的实例能像内建对象一样进行内建函数操作

对象转字符串函数
    repr(obj)  返回一个能代表此对象的表达式字符串,通常
        eval(repr(obj)) == obj
        这个字符串通常是给python解释执行器运行用的
    str(obj)   通过给定的对象返回一个字符串(这个字符串通常是给人看的)
>>> s = 'hello'
>>> s1 = str(s)
>>> s2 = repr(s)
>>> print(s1, s2)

对象转字符串函数的重写方法
    repr(obj) 函数的重写方法:
    def __repr__(self):

    str(obj) 函数的重写方法:
    def __str__(self):
说明:
    1.str(obj) 函数先查找,obj.__str__()方法,调用此方法并返回结果
    2.如果没有__str__方法时,则返回__repr__方法的结果并返回
    3.如果obj.__repr__方法不存在,则调用object类的__repr__实例方法显示<__main__.XXXX object at 0xaabbccdd>
示例:
  myfile.py


其他内建函数的重写方法:
  __abs__        abs(obj) 
  __len__        len(obj) 必须返回整数
  __reversed__   reversed(obj) 必须为可迭代对象
  __round__      round(obj)

数值转换函数的重写
  __complex__    complex(obj)
  __int__        int()
  __float__      float()
  __bool__       bool()

布尔测试函数重写
格式:
    __bool__
作用:
    用于bool(obj)函数的取值
    用于if 语句的真值表达式中
    用于while语句的真值表达式中
说明:
    1.当自定义的类内有 __bool__(self)方法时,以此方法的返回值作为bool(obj)的返回值
    2.当不存在__bool__(self) 方法时,bool(x)返回__len__(self)方法的返回值是否为0来测试布尔值
    3.当不存在__len__(self) 方法时,直接返回True


迭代器(高级)
    可以通过next(it)函数取值的对象就是迭代器
迭代器协议
    迭代器协议是指对象能够使用next函数获取下一项数据,在没有下一项数据时,触发一个StopIteration异常来终止迭代的约定
迭代器协议实现方法:
    __next__(self) 方法来实现迭代器协议
语法形式:
class MyIterator:
    def __next__(self):
        迭代器协议
        return 数据
什么是可迭代对象
    是指能用iter(obj)函数返回迭代器的对象(实例)
    可迭代对象内部需要定义__iter__(self)方法来返回迭代器对象

1.修改原有学生信息管理系统,将学生对象的,全部属性都变为私有属性不让外部直接访问,实现封装

2.写一个列表类Mylist实现存储整数列表
class MyList:
    def __init__(self, iterator):
        self.data = ...
让此类对象能用for 语句进行迭代访问

L = MyList(range(5))
print(L)
L2 = [x ** 2 for x in L]
print(L2)

3.写一个类 Fibonacci 实现迭代器协议,此类对象可以作为可迭代对象生成相应的斐波那契数
1  1  2  3  5
class Fibonacci:
    def __init__(self,n)  # n代表个数

实现如下
for x in Fibonacci(10):
    print(x)
L = [x for x in Fibonacci(50)]
print(L)
F = fibonacci(30)
print(sum(F))

 

 


day20

对象的属性管理函数:
    getattr(obj, name[,default])
    从一个对象得到对象的属性,getattr(x,'y')等同于x.y,当属性不存在时,如果给出default参数,则返回default,如果没有给出default,则产生一个AttributeError
    hasattr(obj, name)
    用给定的name返回对象obj是否有此属性,此种做法可以避免在getattr(obj, name)是引发错误
    setattr(obj, name, value)
    给对象obj的名为name的属性设置相应的值value; setattr(x,'y',z)等同于 x.y = z
    delattr(obj, name)
    删除对象obj中的name属性,delattr(x,'y')等同于 del x.y


异常(高级)
  可以用于异常的语句:
    try-except   # 捕获异常
    try-finally  # 任何流程都要执行的语句
    raise        # 抛出异常
    assert       # 根据条件抛出异常

with 语句
语法:
with 表达式1 [as 变量1], 表达式2 [as 变量2],...
    语句块
作用:
    使用于对资源进行访问的场合,确保使用过程中不管是否发生异常都会执行必要的'清理操作',并释放资源
    (如:文件使用自动关闭,线程中锁的自动获取和释放等)
说明:
    执行表达式 as子句中的变量绑定生成的对象
    with语句并不改变异常的状态
示例:
# with.py
with open('a.txt') as f:
    for x in f:
        print(f)


环境管理器
  类内有__enter__和__exit__实例方法的类被成为环境管理器
  能够用with进行管理的对象必须是环境管理器
说明:
    __enter__将在进入with语句是被调用并返回有as变量绑定的对象
    __exit__将在离开with语句时调用,且可以用参数来判断在离开with语句时是否有异常发生并做出相应的处理


运算符重载
    让自定义的类生成的对象(实例)能够使用运算符进行操作
作用:
    1.让自定义的类的实例能够进行运算符操作
    2.让程序简洁易读
    3.对自定义对象将运算符赋予新的运算规则
说明:
    运算符重载方法的参数已经有固定的含义,不介意改变原有的意义

算术运算符重载
       方法名            运算符和表达式    说明
__add__(self, rhs)       self + rhs     加法
__sub__(self, rhs)       self - rhs     减法
__mul__(self, rhs)       self * rhs     乘法
__truediv__(self, rhs)   self / rhs     除法
__floordiv__(self, rhs)  self // rhs    地板除
__mod__(self, rhs)       self % rhs     求余
__pow__(self, rhs)       self ** rhs    幂


反向算术运算符的重载
    当运算符的左侧为内建类型,右侧为自定义类型的对象进行算术运算符运算时,会出现TypeError错误
    因无法修改内建类型的代码来实现运算符重载,此时需要使用反向运算符重载

       方法名            运算符和表达式    说明
__radd__(self, lhs)      lhs +  self    加法
__rsub__(self, lhs)      lhs -  self    减法
__rmul__(self, lhs)      lhs *  self    乘法
__rtruediv__(self, lhs)  lhs /  self    除法
__rfloordiv__(self, lhs) lhs // self    地板除
__rmod__(self, lhs)      lhs %  self    求余
__rpow__(self, lhs)      lhs ** self    幂


复合赋值算术运算符的重载
    以复合赋值算术运算符 x += y 为例,此运算会优先调用 x.__iadd__(y)方法,如果没有__iadd__方法时会将复合赋值运算拆解为 x = x + y,然后调用 x = x.__add__(y)方法,如果不存在__add__方法则会触发 TypeError异常

       方法名            运算符和表达式    说明
__iadd__(self, rhs)       self += rhs     加法
__isub__(self, rhs)       self -= rhs     减法
__imul__(self, rhs)       self *= rhs     乘法
__itruediv__(self, rhs)   self /= rhs     除法
__ifloordiv__(self, rhs)  self //= rhs    地板除
__imod__(self, rhs)       self %= rhs     求余
__ipow__(self, rhs)       self **= rhs    幂


比较运算符重载
       方法名            运算符和表达式    说明
__lt__(self, rhs)       self <  rhs     
__le__(self, rhs)       self <= rhs     
__gt__(self, rhs)       self >  rhs     
__ge__(self, rhs)       self >= rhs     
__eq__(self, rhs)       self == rhs     
__ne__(self, rhs)       self != rhs     


位运算符重载
__invert__(self)         ~self
__and__(self, rhs)       self & rhs
__or__(self, rhs)        self | rhs
__xor__(self, rhs)       self ^ rhs     
__lshift__(self, rhs)    self << rhs
__rshift__(self, rhs)    self >> rhs
反向位运算符重载
__rand__(self, lfs)       lfs &  self
__ror__(self, lfs)        lfs |  self
__rxor__(self, lfs)       lfs ^  self     
__rlshift__(self, lfs)    lfs << self
__rrshift__(self, lfs)    lfs >> self


一元运算符重载
__invert__(self)         ~self
__pos__(self)            +self
__neg__(self)            -self


in / not in 运算符的重载
重载方法:
def __contains__(self, e):
    ....

索引 / 切片运算符的重载
      方法名               运算符和表达式     说明
__getitem__(self, i)      x = self[i]    索引/切片取值
__setitem__(self, i, val) self[i] = val  索引/切片赋值
__delitem__(self, i)      del self[i]    删除索引/切片
说明:
    让自定义的类的对象能够支持索引和切片操作

slice 函数
    用于创建一个slice切片对象,此对象存储切片的信息
slice(start=None, Stop=None, Step=None)
slice对象的属性
   s.start 切片的起始值,默认为None
   s.stop  切片的终止值,默认为None
   s.step  切片的步长,默认为None


特性属性 @property
    实现其他语言所拥有的 getter 和 setter 的功能
作用:
    用来模拟一个属性
    通过 @property 装饰器可以对模拟属性的取值和赋值加以控制
示例:
  property.py

  练习
实现有序集合类 OrderSet() 能是实现两个集合的交集&,全集|,补集-,对称补集^,==/!=,in/not in,等操作
要求集合内部用list存储
class OrderSet:
    ...

s1 = OrderSet([1, 2, 3, 4])
s2 = OrderSet([3, 4, 5])
print(s1 & s2)
print(s1 | s2)
print(s1 ^ s2)
if OrderSet([1, 2, 3]) != OrderSet([3, 4, 5]):
    print('不相等')
if s2 == OrderSet([3, 4, 5]):
    print('s2 == OrderSet([3, 4, 5]) is true')
if 2 in s1:
    print('2在s1中')


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值