《疯狂Python讲义》之文件IO

放肆的年华 提交于 2020-01-19 12:55:33

使用pathlib模块操作目录

pathlib模块提供了一组面向对象的类,这些类可代表各种操作系统上的路径,程序可通过这些类操作路径。

  • PurePath:代表并不访问实际文件系统的“纯路径”
  • Path:代表访问实际文件系统的“真正路径”

PurePath的基本功能

程序在创建PurePath和Path时,即可传入单个路径字符串,也可以传入多个路径字符串,PurePath会将它们拼接成一个字符串。

pp= PurePosixPath ( ’ crazyit ’,’some/path ’,’info ’ ) 
#看到输出 UNIX 风格的路径
print(pp) # crazyit/ some/path/info

如果在创建PurePath不传入任何参数,系统默认创建代表当前路径的PurePath

#如果不传入参数,默认使用当前路径
pp = Pure Path () 
print(pp) #.

如果在创建PurrePath时传入的参数包含多个根路径,则只有最后一个根路径及后面的子路径生效

#如果传入的参数包含多个根路径 ,则只有最后一个根路径及后面的子路径生效
pp= PurePosixPath ('/etc''/usr','lib64')
print(pp) # / usr/ lib64 
pp = PureW ndowsPath ( 'c: /Windows','d:info' ) 
print (pp) # d : info

如果在创建PurePath时传入的路径字符串有多个斜杠和点号,系统会直接忽略它们,但不会忽略两点,因为两点在路径中有实际意义

#在路径字符串中多出来的斜杠和点号(代表当前路径)都会被忽略
pp= PurePath ('foo//bar')
print(pp) # foo\ bar 
pp= PurePath ('foo/./bar') 
print(pp) # foo\bar

PurePath对象支持各种比较运算符,既可比较是否相等,也可比较大小—实际上就是比较它们的路径字符串

PurePath的属性和方法

PurePath提供了不少属性和方法,这些属性和方法主要还是用于操作路径字符串:

  • PurePath.parts:该属性返回路径字符串中所包含的各部分
  • PurePath.drive:该属性返回路径字符串中的驱动器盘符
  • PurePath.root:该属性发返回路径字符串中的根路径
  • PurePath.anchor:该属性返回路径字符串中的盘符和根路径
  • PurePath.parents:该属性返回当前路径的全部父路径
  • PurePath.parent:该属性返回当前路径的上一级路径,相当于parents[0]的返回值
  • PurePath.name:该属性返回当前路径中的文件名
  • PurePath.suffixes:该属性返回当前路径中的文件所有后缀名
  • PurePath.suffix:该属性返回当前路径中的文件后缀名
  • PurePath.stem:该属性返回当前路径中的主文件名
  • PurePath.as_posix():将当前路径转换成UNIX风格的路径
  • PurePath.as_uri():将当前路径转换成URL
  • PurePath.as_absolute():判断当前路径是否为绝对路径
  • PurePath.joinpath(*other):将多个路径连接在一起
  • PurePath.match(pattern):判断当前路径是否匹配指定通配符
  • PurePath.relative_to(*other):获取当前路径中去除基准路径之后的结果
  • PurePath.with_name(name):将当前路径中的文件名替换成新文件名
  • PurePath.with_suffix(suffix):将当前路径中的文件后缀名替换成新的后缀名

Path的功能和用法

Path是PurePath的子类,它除支持PurePath的各种操作、属性和方法之外,还会真正访问底层的文件系统,包括判断Path对应的路径是否存在,获取Path对应路径的各种属性,甚至可以对文件进行读写。
Path提供了两个子类:PosixPath和WindowsPath,前者代表UNIX风格的路径,后者代表Windows风格的路径。

  • is_xxx():判断该Path对应的路径是否为xxx
  • exists():判断该Path对应的目录是否存在
  • iterdir():返回Path对应目录下的所有目录和文件
  • glob():获取Path对应目录及其子目录下匹配指定模式的所有文件

使用os.path操作目录

在os.path模块下提供了一些操作目录的方法:

  • exists():判断该目录是否存在
  • getctime():获取目录的创建时间
  • getmtime():获取目录的最后一次修改时间
  • getatime():获取目录的最后一次访问时间
  • getsize():获取指定文件的大小

使用fnmatch处理文件名匹配

fnmatch匹配支持如下通配符:

  • *:可匹配任意个任意字符
  • ?:可匹配一个任意字符
  • [字符序列]:可匹配中括号里字符序列中的任意字符
  • [!字符序列]:可匹配不在中括号里字符序列中的任意字符
  • fnmatch.fnmatch(filename,pattern):判断指定文件名是否匹配指定pattern
  • fnmatch.fnmatchcase(filename,pattern):与上一个函数功能大致相同,只是该函数区分大小写
  • fnmatch.filter(filename,pattern):该函数对names列表进行过滤,返回names列表中匹配pattern的文件名组成的子集合
  • fnmatch.translate(filename,pattern):该函数用于将一个UNIX shell风格的pattern转换为正则表达式pattern

打开文件

Python提供了一个内置的open()函数,用于打开指定文件,该函数的语法格式如下:

open(file_name [,access_mode][,buffering])

打开文件之后,就可调用文件对象的属性和方法:

  • file.closed:该属性返回文件是否已经关闭
  • file.mode:该属性返回被打开文件的访问模型
  • file.name:该属性返回文件的名称

文件打开模式

模式 意义
r 只读模式
w 写模式
a 追加模式
+ 读写模式
b 二进制模式,可与其他模式结合使用

如果使用r或r+模式打开文件,则要求被打开的文件本身是存在的,r或r+模式不能创建文件;如果使用w、w+、a、a+模式打开文件,则文件可以不存在,open()函数会自动创建新文件;b模式可被追加到其他模式上,用于代表以二进制的方式来读写文件内容

读取文件

Python既可使用文件对象的方法来读取文件,也可使用其他模块的函数来读取文件

按字节或字符读取

文件对象提供了read()方法来按字节或字符读取文件内容,到底是读取字节还是字符,则取决于是否使用了b模式,如果使用了b模式,则每次读取一个字节;如果没有使用b模式,则每次读取一个字符。在调用该方法时可传入一个整数作为参数,用于指定最多读取多少个字节或字符。

如果要读取的文件所使用的字符集和当前操作系统的字符集不匹配,则有两种解决方式:

  • 使用二进制模式读取,然后用bytes的decode()方法恢复成字符串
  • 利用codes模块的open()函数来打开文件,该函数在打开文件时允许指定字符集
# 指定使用二进制方式读取文件内容
f = open("read_test3.py", 'rb', True)
# 直接读取全部文件,并调用bytes的decode将字节内容恢复成字符串
print(f.read().decode('utf-8'))
f.close()

按行读取

如果程序要读取行,通常只能用文本方式来读取,文件对象提供了如下两个方法来读取行:

  • readline([n]):读取一行内容,如果指定了参数n,则只读取此行内的n各字符
  • readlines():读取文件内所有行
import codecs
# 指定使用utf-8字符集读取文件内容
f = codecs.open("readline_test.py", 'r', 'utf-8', buffering=True)
while True:
    # 每次读取一行
    line = f.readline()
    # 如果没有读到数据,跳出循环
    if not line: break
    # 输出line
    print(line, end='')
f.close()

程序使用readlines()方法一次读取文件内所有行,代码如下:

import codecs
# 指定使用utf-8字符集读取文件内容
f = codecs.open("readlines_test.py", 'r', 'utf-8', buffering=True)
# 使用readlines()读取所有行,返回所有行组成的列表
for l in f.readlines():
    print(l, end='')
f.close()

使用fileinput读取多个输入流

fileinput模块提供了如下函数可以把多个输入流合并在一起:

  • fileinput.input(files=None,inplace=False,backup="",bufsize=0,mode=‘r’,openhook=None):该函数中的files参数用于指定多个文件输入流,该函数返回一个FileInput对象,可通过for循环来遍历文件的每一行。
  • fileinput.filename():返回正在读取的文件的文件名
  • fileinput.fileno():返回当前文件的文件描述符,该文件描述符是一个整数
  • fileinput.filelineno():返回当前读取的行在其文件中的行号
  • fileinput.isfirstline():返回当前读取的行在其文件中是否为第一行
  • fileinput.isstdin():返回最后一行是否从sys.stdin读取
  • fileinput.nextfile():关闭当前文件,开始读取下一个文件
  • fileinput.close():关闭FileInput对象

文件迭代器

文件对象本身就是可变量的,因此程序完全可以使用for循环来遍历文件内容。

import codecs
# 指定使用utf-8字符集读取文件内容
f = codecs.open("for_file.py", 'r', 'utf-8', buffering=True)
# 使用for循环遍历文件对象
for line in f:
    print(line, end='')
f.close()
# 将文件对象转换为list列表
print(list(codecs.open("for_file.py", 'r', 'utf-8', buffering=True)))

sys.stdin也是一个类文件对象,程序同样可以使用for循环遍历sys.stdin,意味着程序可以通过for循环来获取用户的键盘输入。

import sys
# 使用for循环遍历标准输入
for line in sys.stdin:
    print('用户输入:', line, end='')

管道输入

管道的作用在于:将前一个命令的输出,当成下一个命令的输入。管道输入的语法如下:

cmd1 | cmd2 | cmd3 ...

上面语法的作用是:cmd1命令的输出,将会传给cmd2命令作为输入;cmd2命令的输入,又会传给cmd3命令作为输出。

使用with语句

Python提供了with语句来管理资源关闭。比如可以把打开的文件放在with语句中,这样with语句就会帮我们自动关闭文件。
with语句的语法格式如下:

with context_expression[as target(s)]:
    with 代码块
import codecs
# 使用with语句打开文件,该语句会负责关闭文件
with codecs.open("readlines_test.py", 'r', 'utf-8', buffering=True) as f:
    for line in f:
        print(line, end='')

使用linecache随机读取指定行

linecache模块允许从Python源文件中随机读取指定行,并在内部使用缓存优化存储,它会用UTF-8字符集来读取文本文件。实际上只要该文件使用UTF-8字符集存储,就可以用linecache模块读取。

  • linecache.getline(filename,lineno,module_globals=None):读取指定模块中指定文件的指定行,其中filename指定文件名,lineno指定行号
  • linecache.clearcache():清空缓存
  • linecache.checkcache(filename=None):检查缓存是否有效

写文件

如果以r+、w、w+、a、a+模式打开文件,则都可以写入。其中,当以r+、w、w+模式打开文件时,文件指针位于文件开头处;当以a、a+模式打开文件时,文件指针位于文件结尾处;当以w或w+模式打开文件时,程序会立即清空文件的内容。

文件指针的概念

文件指针用于标明文件读写的位置。文件对象提供了以下方法来操作文件指针:

  • seek(offset[,whence]):该方法把文件指针移动到指定位置
  • tell():判断文件指针的位置

输出内容

文件对象提供的写文件的方法主要有两个:

  • write(str或bytes):输出字符串或字节串,只有以二进制模式(b模式)打开的文件才能写入字节串
  • writelines(可迭代对象):输出多个字符串或多个字节串

os模块的文件和目录函数

与目录相关的函数

  • os.getcwd():获取当前目录
  • os.chdir(path):改变当前目录
  • os.fchdir(fd):通过文件扫描符改变当前目录
  • os.chroot(path):改变当前进程的根目录
  • os.listdir(path):返回path对应目录下的所有文件和子目录
  • os.mkdir(path[,mode]):创建path对应的目录,其中mode用于指定该目录的权限
  • os.makedirs(path[,mode]):更强大,递归创建目录
  • os.rmdir(path):删除path对应的空目录
  • os.removedirs(path):递归删除目录
  • os.rename(src,dst):重命名文件或目录,将src重名为dst
  • os.renames(old,new):对文件或目录进行递归重命名

与权限相关的函数

  • os.access(path,mode):检查path对应的文件或目录是否具有指定权限,该函数的第二个参数可能是:
    • os.F_OK:判断是否存在
    • os.R_OK:判断是否可读
    • os.W_OK:判断是否可写
    • os.X_OK:判断是否可执行
  • os.chmod(path,mode):更改权限
    • stat.S_IXOTH:其他用户有执行权限
    • stat.S_IWOTH:其他用户有写权限
    • stat.S_IROTG:其他用户有读权限
    • stat.S_IRWXO:其他用户有全部权限
    • stat.S_IXGRP:组用户有执行权限
    • stat.S_IWGRP:组用户有写权限
    • stat.S_IRGRP:组用户有读权限
    • stat.S_IRWXG:组用户有全部权限
    • stat.S_IXUSR:所有者有执行权限
    • stat.S_IWUSR:所有者有些权限
    • stat.S_IRUSR:所有者有读权限
    • stat.S_IRWXU:所有者有全部权限
    • stat.S_IREAD:Windows将该文件设为只读
    • stat.S_IWRITE:Windows将该文件设为可写
  • os.chown(path,uid,gid):更改文件的所有者
  • os.fchmod(fd,mode):改变一个文件的访问权限
  • os.fchown(fd,uid,gid):改变文件的所有者

与文件访问相关的函数

  • os.open(file,flags[,mode]):打开一个文件,并设置打开选项,mode参数可选
    • os.O_RDONLY:以只读的方式打开
    • os.O_WRONLY:以只写的方式打开
    • os.O_RDWR:以读写的方式打开
    • os.O_NONBLOCK:打开时不阻塞
    • os.O_APPEND:以追加的方式打开
    • os.O_CREAT:创建并打开一个新文件
    • os.O_TRUNC:打开一个文件并截断它的长度为0
    • os.O_EXCL:创建文件时,如果指定的文件存在,则返回错误
    • os.O_SHLOCK:自动获取共享锁
    • os.O_EXLOCK:自动获取独立锁
    • os.O_DIRECT:消除或减少缓存效果
    • os.O_FSYNC:同步写入
    • os.O_NOFOLLOW:不追踪软链接
  • os.read(fd,n):从文件描述符fd中读取最多n个字节,返回读到的字节串
  • os.write(fd,str):将字节串写入文件描述符fd中,返回实际写入的字节串长度
  • os.close(fd):关闭文件描述符fd
  • os.lseek(fd,pos,how):该函数同样用于移动文件指针。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!