Python完美诠释"高内聚"概念的 IO 流 API 体系结构

历览千载书,时时见遗烈。这篇文章主要讲述Python完美诠释"高内聚"概念的 IO 流 API 体系结构相关的知识,希望能为你提供帮助。
1. 前言第一次接触 python 语言的 IOAPI 时,是惊艳的。相比较其它语言所提供的 IO 流 API 。
无论是站在使用者的角度还是站在底层设计者的角度,都可以称得上无与伦比。
很多人在学习 java 语言中的 IO 流 API 时,几乎是崩溃的。其 API 太多、API 之间的关系过于复杂。类的层次结构需要花费很多时间才能搞明白。API 设计者未免有炫技之嫌。
而 Python 的 IO 流操作,才真正应了哪句话:人生苦短,我学 python 。
以 open( ) 函数 为操作起点,便捷、快速地完成所有操作,绝对算得上轻量级设计的典范,且高度诠释了“高内聚”概念。使用起来颇有“四两拨千金”的轻松。
通过了解 open( ) 函数的参数设计,其开闭设计思想可谓使用到了极致。
2.open() 函数2.1 函数原型

def open(file, mode=r, buffering=None, encoding=None, errors=None, newline=None, closefd=True):
……

2.2 函数功能
打开一个指定位置的文件并返回 IO 流对象。
2.3 函数参数
【Python完美诠释"高内聚"概念的 IO 流 API 体系结构】 Tip: open( ) 函数的参数看起来虽然有点多,在使用时,很多参数都可以采用默认设置,它会提供最优的工作方案。
  • file 参数: 指定文件位置。可以是一个字符串描述的文件路径,也可以是一个文件描述符(int 类型)。
Tip: 当使用字符串描述时,可以是绝对路径,也可以是相对路径。
绝对路径: 以绝对位置作为路径的起点。 不同的操作系统中会有差异性,windows 以逻辑盘符为绝对起点,Liunx 以 "/" 根目录为绝对起点。
file=open("d:/guoke.txt")

Tip: 上述代码运行时,需要保证在系统的 d 盘下有一个名字 "guoke.txt" 的文件。
相对路径: 所谓相对路径指以某一个已经存在的路径(或叫参照目录、当前目录)做起点。 默认情况下,相对路径以当前项目目录作为参照目录。可以使用 os 模块 中的getcwd( ) 方法获取当前参照目录的信息。
import os
print(os.getcwd())
# 本代码的测试项目放在 d:\\myc 下; 项目名称:filedmeo
# 输出结果
# D:\\myc\\filedmeo

如下代码需要保证在项目目录中存在 " guoke.txt "
file = open("guoke.txt")
# 执行时, python 解释器会自动拼接一个完整路径 D:\\myc\\filedmeo\\guoke.txt

参照目录 可以是不固定的,而是可变的。
改变相对路径的参考目录:
import os
# 把 d 盘作为当前目录
os.chdir("d:/")
print(os.getcwd())
file = open("guoke.txt")
# python 解释器会从 d 盘根目录下查找 guoke.txt 文件

描述符: 使用 open( ) 函数打开一个文件后,python 解释器系统会为此文件指定一个唯一的数字标识符。可以用此描述符作为 open( ) 参数。
file = open("guo_ke.txt")
# fileno() 获取文件的描述符
file1 = open(file.fileno())

Tip: 用户文件的描述符从 3 开始。0,1,2 是系统保留文件描述符。
- 0:表示标准输入(键盘)设备描述符。
> file = open(0)
> print("请输入一个数字:")
> res = file.readline()
> print("回显:", res)
>
> 输出结果
> 请输入一个数字:
> 88
> 回显: 88
>
>

- 1:表示标准输出设备(显示器)描述符。
> file = open(1, "w")
> file.write("you are welcome!")
> #类似于 print("you are welcome!") 的功能
>

- 2:表示标准错误输出设备(显示器)描述符。
> file = open(2, "w")
> file.write("you are welcome!")
> #输出文字会以红色亮显
>

  • mode: 文件操作模式。默认为 "r" ,表示只读模式。
模式关键字
描述
异常
|r| 以只读方式打开文件 | 文件不存时,会抛出 FileNotFoundError 异常 |
| ‘r+’ | 以可读、可写方式打开文件 | 文件不存时,会抛出 FileNotFoundError 异常 |
| ‘w’ | 以可写方式打开文件 | 文件不存在时,创建一个字节 0 的空文件 |
| ‘w+’ | 以可写、可读方式打开文件(清空原内容) | 文件不存在时,创建一个字节 0 的空文件 |
| ‘a’ | 以追加方式打开文件 | 文件不存在时,创建一个字节 0 的空文件 |
| ‘a+’ | 以可追加、可读方式打开文件 | 文件不存在时,创建一个字节 0 的空文件 |
| ‘t’ | 以文本文件格式打开文件 | 默认 |
| ‘b’ | 以二进制格式打开文件 ||
| ‘x’ | 创建空文件并且可写 | 文件存在时,抛出 FileExistsError 异常 |

只要在模式组合中有 r关键字,则文件必须提前存在:
file = open("guo_ke.txt")
file = open("guo_ke.txt", r)
file = open("guo_ke.txt", rt)
file = open("guo_ke.txt", r+t)

只要在模式组合中有 ‘w’ 关键字,则文件可以不必预先存在,如果存在,则原文件中内容会被清空。


# 可写
file = open("guo_ke.txt", w)
# 可写、可读
file = open("guo_ke.txt", w+)

只要在模式组合中有 ‘a’ 关键字,则文件可以不必预先存在,如果存在,原文件中内空不会被清空

# 追加写
file = open("guo_ke.txt", a)
# 追加写、且可读
file = open("guo_ke.txt", a+)

  • buffering: 设置缓冲策略。可取值为 0、1、> 1 。
  • 0: 在二进制模式下关闭缓冲。
  • 1:在文本模式下使用行缓冲。
行缓冲:以行数据为单位进行缓存。
  • > 1 的整数: 指定缓冲区的大小(以字节为单位)。
如果没有指定 buffering 参数,则会提供默认缓冲策略:
  • 二进制文件使用固定大小的缓冲块。
在许多系统上,缓冲区的长度通常为 4096 或 8192 字节。
  • "Interactive" 文本文件( isatty() 返回 True 的文件)使用行缓冲。其他文本文件使用和二进制文件相同的缓冲策略。
isatty( ) 方法检测文件是否连接到一个终端设备。
  • encoding: 指定解码或编码文件时使用的编码名称。
只能用于文本文件。默认使用平台编码。
  • errors: 指定如何处理编码和解码时抛出的错误。可选项如下:
  • strict: 如果存在编码错误,则引发 ValueError 异常。 默认值 None 具有相同的效果。
  • ignore: 忽略错误。有可能会数据丢失。
  • replace:会将替换标记(例如 ? )插入有错误数据的地方。
  • newline:在读或写文本内容时如何处理换行符号。可取值 None, ,\\n,\\r 和 \\r\\n。
OS 不同,换行符的描述也有差异。Unix 的行结束 \\n、Windows 中为 \\r\\n
  • 从流中读数据时,如果 newline 为 None,则启用平台约定换行模式。
  • 写入流时,如果 newline 为 None,则写入的任何 \\n 字符都将转换为系统默认行分隔符 。如果 newline 是或 \\n,则直接写入。如果 newline 是任何其他合法值,则写入的任何 \\n 字符将被转换为给定的字符串。
  • closefd:
file = open("guo_ke.txt",closefd=False)

输出结果
Traceback (most recent call last):
File "D:/myc/filedmeo/文件嵌套.py", line 1, in < module>
file = open("guo_ke.txt",closefd=False)
ValueError: Cannot use closefd=False with file name

如果通过一个字符串路径描述打开文件, closefd 必须为 True (默认值),否则将引发错误。
file = open("guo_ke.txt", )
# 通过 file 文件的描述符打开文件
file1 = open(file.fileno(), closefd=False)
file1.close()
print("先打开文件:", file.closed)
print("后打开文件:", file1.closed)

输出结果
先打开文件: False
后打开文件: True

当 open file1 文件时设置为closefd=False ,则当 file1 文件关闭后,file 文件将保持打开状态。
  • opener:可理解为 open( ) 函数是一个高级封装对象,本质是通过 opener 参数接入了一个真正的具有底层文件操作能力的接口。
import os

def opener(path, flags):
return os.open(path, flags)
# 调用 opener(guo_ke.txt,r) 时的参数来自于 open() 的第一个和第二个
with open(guo_ke.txt, r, opener=opener) as f:
print(f.read())

默认 opener 参数引用的就是 os.open( ) 方法。
3. 读写操作调用 open( ) 函数后会返回一个 IO流对象。IO 流对象中提供了常规的与读写相关的属性和方法。
class IO(Generic[AnyStr]):
#返回文件的读写模式
@abstractproperty
def mode(self) -> str:
pass
#返回文件的名称
@abstractproperty
def name(self) -> str:
pass
#关闭文件
@abstractmethod
def close(self) -> None:
pass
#判断文件是否关闭
@abstractproperty
def closed(

    推荐阅读