【Python】第七章 I/O

该文章内容整理自《Python编程:从入门到实践》、《流畅的Python》、以及网上各大博客

I/O

基本输入输出

input()

Python2中有 input() 和 raw_input() 两个内置的函数可从标准输入读取数据,它默认来自键盘。但在Python3中,raw_input()函数已被弃用

  • input():以字符串形式读入数据,若要读入其他形式则需要另行转换
x = int(input("请输入x="))
y = int(input("请输入y="))
z = x + y
print("x + y = ", z)
  • raw_input():从标准输入中以字符串形式读取一个行,并去掉结尾的换行符

print()

print 在 Python3 中是一个函数,但在 Python2 中只是一个关键字。print()的一般形式为
print(*objects, sep=’ ‘, end=’\n’, file=sys.stdout, flush=False)
其中

  • objects:输出列表,一次输出多个用逗号分隔的不同类型的对象
  • sep:分隔字符,表示输出多个对象时用来间隔对象的字符。默认值是一个空格
  • end:结束字符,表示输出完对象后用来什么字符结尾。默认值是换行符 \n
  • file:写入的文件对象
  • flush:表示流是否会被强制刷新。默认为 False,当为 True 时,在输出完对象后,光标移动到输出对象前的位置,下一次的输出会覆盖本次输出

print()的格式化输出可通过字符串的format()函数来实现

文件操作

Python 提供了内置的文件对象,以及对文件、目录进行操作的内置模块,通过这些技术可以很方便地将数据保存到文件中。Python 中对文件的操作有很多种,常见的操作包括创建、删除、修改权限、读取、写入等,这些操作可大致分为以下 2 类:

  • 删除、修改权限:作用于文件本身,属于系统级操作。对文件的系统级操作功能单一,比较容易实现,可以借助 Python 中的专用模块(os、sys 等)的指定函数来实现。例如删除文件“a.txt”可通过调用 os 模块中的 remove 函数来完成,即os.remove(“a.txt”)
  • 写入、读取:是文件最常用的操作,作用于文件的内容,属于应用级操作。文件的应用级操作可以分为以下 3 步,每一步都需要借助对应的函数实现
    1. 打开文件:使用 open() 函数,该函数会返回一个文件对象
    2. 对已打开文件做读/写操作:读取文件内容可使用 read()、readline() 以及 readlines() 函数;向文件中写入内容,可以使用 write() 函数
    3. 关闭文件:完成对文件的读/写操作之后,最后需要关闭文件,可以使用 close() 函数

文件路径

文件对象有文件名和路径两个关键属性。对于路径,在 Windows 中路径用反斜杠“\”作分隔符;在 Linux 中则用斜杠“/”。而为了兼容这两种情况,Python提供了 os.path.join() 函数来将多个组件合成路径。 若各组件名首字母不包含分隔符,则函数会自动加上系统对应的分隔符;若有一个组件是一个绝对路径,则在它之前的所有组件均会被舍弃。如

import os

p1 = os.path.join('home', 'develop', 'code')
# home/develop/code

p2 = os.path.join('home', '/develop', 'code')
# /develop/code

关于当前工作路径、绝对路径和相对路径

  1. 当前工作路径:表示运行当前程序所在目录。Python提供了 os.getcwd() 和 os.chdir(new_path) 函数来查看和修改当前路径
  2. 绝对路径:从根文件夹开始,Window 系统中以盘符(C: 、D:)作为根文件夹,而 OS X 或者 Linux 系统中以 / 作为根文件夹
  3. 相对路径:相对于当前工作路径所在的位置。在使用相对路径表示某文件所在的位置时,使用 .\ 表示当前所在目录,…\ 表示当前所在目录的父目录

os.path 模块还提供了一些函数来处理绝对路径和相对路径

  • os.path.abspath(path):返回 path 参数的绝对路径的字符串,这是将相对路径转换为绝对路径的简便方法
  • os.path.isabs(path):如果参数是一个绝对路径,就返回 True;如果是一个相对路径,就返回 False
  • os.path.relpath(path, start):返回从 start 路径到 path 的相对路径的字符串。如果没有提供 start,就使用当前工作目录作为开始路径
  • os.path.dirname(path):返回一个字符串,它包含 path 参数中最后一个斜杠之前的所有内容
  • os.path.basename(path):返回一个字符串,它包含 path 参数中最后一个斜杠之后的所有内容
  • os.path.split(path):返回由 path 参数的目录名称和基本名称组成的元组,即将路径拆成所在目录路径和文件名。虽然可以直接使用(os.path.dirname(path), os.path.basename(path)),但使用os.path.split(path)更为便捷
  • os.path.exists(path):如果 path 参数所指的文件或文件夹存在返回 True,否则返回 False
  • os.path.isfile(path):如果 path 参数存在且为文件则返回 True,否则返回 False
  • os.path.isdir(path):如果 path 参数存在且为文件夹则返回 True,否则返回 False

打开文件

Python 内置的 open() 方法用于打开一个文件,并返回文件对象。如果该文件无法被打开,会抛出 OSError。其一般形式为
file object = open(file, mode=‘r’, buffering=-1, encoding=None)
其中

  • file:表示将要打开的文件的路径(绝对路径或者当前工作目录的相对路径)
  • mode:决定打开文件的模式为只读,写入,追加等。默认只读 r
    • t:文本模式
    • x:写模式,新建一个文件,如果该文件已存在则会报错
    • b:二进制模式
    • +:打开一个文件进行更新(可读可写)
    • U:通用换行模式(Python 3 不支持)
    • r:以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式
    • rb:以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。一般用于非文本文件如图片等
    • r+:打开一个文件用于读写。文件指针将会放在文件的开头
    • rb+:以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。一般用于非文本文件如图片等
    • w:打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件
    • wb:以二进制格式打开一个文件只用于写入。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等
    • w+:打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件
    • wb+:以二进制格式打开一个文件用于读写。如果该文件已存在则打开文件,并从开头开始编辑,即原有内容会被删除。如果该文件不存在,创建新文件。一般用于非文本文件如图片等
    • a:打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
    • ab:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入
    • a+:打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写
    • ab+:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写
  • buffering:如果buffering的值被设为0,就不会有寄存。如果buffering的值取1,访问文件时会寄存行。如果将buffering的值设为大于1的整数,表明了这就是的寄存区的缓冲大小。如果取负值,寄存区的缓冲大小则为系统默认。如果不使用缓冲区,则程序在执行 I/O 操作时,内存和外设就必须进行同步读写操作,即内存必须等待外设 I/O 一个字节之后,才能再次 I/O 一个字节。这意味着,内存中的程序大部分时间都处于等待状态
  • encoding:手动设定打开文件时所使用的编码格式,不同平台的 ecoding 参数值也不同,以 Windows 为例,其默认为 cp936(实际上就是 GBK 编码)。一般使用utf8。默认采用 GBK 编码。只在文本模式下使用,否则会抛出 ValueError 异常

一个文件被打开后,就有创建一个file对象,其包含的属性有

  • file.name:返回文件的名称
  • file.mode:返回被打开文件的访问模式
  • file.encoding:返回打开文件时使用的编码格式
  • file.softspace:末尾是否强制加空格
  • file.closed:返回true如果文件已被关闭,否则返回false
  • file.readable():判断文件对象是否可读
  • file.writeable():判断文件对象是否可写

关于本文文件和二进制文件
文本文件通常用来保存肉眼可见的字符,比如 .txt 文件、.c 文件、.dat 文件等,用文本编辑器打开这些文件就能够顺利看懂文件的内容。而二进制文件通常用来保存视频、图片、音频等不可阅读的内容,当用文本编辑器打开这些文件,会看到一堆乱码。但实际上,从数据存储的角度上分析,二进制文件和文本文件没有区别,它们的内容都是以二进制的形式保存在磁盘中的。之所以能看懂文本文件的内容,是因为文本文件中采用的是 ASCII、UTF-8、GBK 等字符编码,文本编辑器可以识别出这些编码格式,并将编码值转换成字符展示出来。而对于二进制文件,文本编辑器无法识别这些文件的编码格式,只能按照字符编码格式胡乱解析,所以最终看到的是一堆乱码
使用 open() 函数以文本格式打开文件和以二进制格式打开文件,唯一的区别是对文件中换行符的处理不同。在 Windows 系统中,文件中用 “\r\n” 作为行末标识符(即换行符),当以文本格式读取文件时,会将 “\r\n” 转换成 “\n”;反之,以文本格式将数据写入文件时,会将 “\n” 转换成 “\r\n”。这种隐式转换换行符的行为,对用文本格式打开文本文件是没有问题的,但如果用文本格式打开二进制文件,就有可能改变文本中的数据(将 \r\n 隐式转换为 \n)。而在 Unix/Linux 系统中,默认的文件换行符就是 \n,因此在 Unix/Linux 系统中文本格式和二进制格式并无本质的区别
总的来说,为了保险起见,对于 Windows平台最好用 b 打开二进制文件;对于 Unix/Linux 平台,打开二进制文件,可以用 b,也可以不用

文件读写

Python 提供了 read()、readline()、readlines()、write() 和 writelines() 函数,以实现在可读模式下读取文件中数据及在可写模式下向文件中写入指定内容的操作

read()

read()函数用于逐个字节或者字符读取文件中的内容。如果文件是以文本模式(非二进制模式)打开的,则 read() 函数会逐个字符进行读取;反之,如果文件以二进制模式打开,则 read() 函数会逐个字节进行读取,并且返回的字符串以b开头,表明为二进制格式。其一般形式为
file.read([size])
其中,file 表示已打开的文件对象;size 作为一个可选参数,用于指定一次最多可读取的字符(字节)个数,此时若在文件没有关闭的情况下再次调用 read() 则会继续在上次光标所在处开始读,如果省略,则默认一次性读取所有内容,但正因为如此,如果文件非常大,尤其是大于内存时,则无法使用read()方法

在使用 read() 函数时,如果 Python 解释器提示 UnicodeDecodeError 异常,其原因在于目标文件使用的编码格式和 open() 函数打开该文件时使用的编码格式不匹配。除了见编码格式调整一致之外,还有一种方法,先使用二进制模式读取文件,然后调用 bytes 的 decode() 方法,使用目标文件的编码格式,将读取到的字节串转换成认识的字符串

readline()

readline()函数用于逐行读取文件中的内容,包含最后的换行符“\n”。其一般形式为
file.readline([size])
其中,file 为打开的文件对象;size 为可选参数,用于指定读取每一行时,一次最多读取的字符(字节)数,此时若在文件没有关闭的情况下再次调用 readline() 则会继续在上次光标所在处开始读 size 个字符或者到换行符为止

注意,由于 readline() 函数在读取文件中一行的内容时,会读取最后的换行符“\n”,再加上 print() 函数输出内容时默认会换行,所以输出结果中会看到多出了一个空行

readlines()

readlines()函数用于一次性读取文件中所有行,并返回一个列表,列表中的每一项为文件中的每一行。速度要比 readline() 快

write()

Python 中的文件对象提供了 write() 函数,可以向文件中写入指定内容。其一般形式为
file.write(string)

另外,在写入文件完成后,一定要调用 close() 函数将打开的文件关闭,否则写入的内容不会保存到文件中。这是因为在写入文件内容时,操作系统不会立刻把数据写入磁盘,而是先缓存起来,只有调用 close() 函数时,操作系统才会保证把没有写入的数据全部写入磁盘文件中。除此之外,如果向文件写入数据后,不想马上关闭文件,也可以调用文件对象内置的 flush() 函数,它可以实现将缓冲区的数据写入文件中

writelines()

Python还提供了 writelines() 函数来实现将字符串列表写入文件中。因而可以直接在使用文件a的 readlines() 函数返回值作为文件b的writelines() 函数的参数,将文件a的内容全部复制到文件b中

注意,使用 writelines() 函数向文件中写入多行数据时,不会自动给各行添加换行符,只会直接按照字符串列表内容写入文件

文件指针

文件指针用于标明文件读写的起始位置。注意,当向文件中写入数据时,如果不是文件的尾部,写入位置的原有数据不会自行向后移动,新写入的数据会将文件中处于该位置的数据直接覆盖掉。为移动文件指针,实现文件内容的随机读写,文件对象提供了 tell() 函数和 seek() 函数

  • tell():用于判断文件指针当前所处的位置。其一般形式为file.tell()。函数返回文件指针位置,位置下标从0开始计算
  • seek():函数用于移动文件指针到文件的指定位置。其一般形式为file.seek(offset[, whence]),其中
    • offset:表示相对于 whence 位置文件指针的偏移量,正数表示向后偏移,负数表示向前偏移。注意,当 offset 值非 0 时,Python 要求文件必须要以二进制格式打开,否则会抛出 io.UnsupportedOperation 错误
    • whence:作为可选参数,用于指定文件指针要放置的位置,该参数的参数值有 3 个选择:0 代表文件头(默认值)、1 代表当前位置、2 代表文件尾

关闭文件

close() 函数是用来关闭已打开文件,在用 open() 函数打开的文件,完成文件读写操作之后,一定要调用 close() 函数将其关闭。除了之前说过会对写文件产生影响外,不使用 close() 函数直接对文件进行系统级别的操作(如删除文件)会报错。其一般形式为
file.close()

with as

为了更好地避免没有使用 close() 函数关闭文件的问题,Python 引入了 with as 语句操作上下文管理器(context manager),自动分配并且释放资源。其一般形式为

with expression [as target]# ...

其中,target 参数用于指定一个变量,该语句会将 expression 指定的结果保存到该变量中

简单的理解,同时包含 __enter__() 和 __exit__() 方法的对象就是上下文管理器。也就是说,上下文管理器必须实现如下两个方法:

  • __enter__(self):进入上下文管理器自动调用的方法,该方法会在 with as 代码块执行之前执行。如果 with 语句有 as子句,那么该方法的返回值会被赋值给 as 子句后的变量;该方法可以返回多个值,因此在 as 子句后面也可以指定多个变量(多个变量必须由“()”括起来组成元组)
  • __exit__(self, exc_type, exc_value, exc_traceback):退出上下文管理器自动调用的方法。该方法会在 with as 代码块执行之后执行。如果 with as 代码块成功执行结束,程序自动调用该方法,调用该方法的三个参数都为 None:如果 with as 代码块因为异常而中止,程序也自动调用该方法,使用 sys.exc_info 得到的异常信息将作为调用该方法的参数。注意,当出现异常时,如果 __exit__() 返回 False(默认不写返回值时,即为 False),则会重新抛出异常,让 with as 之外的语句逻辑来处理异常;反之,如果返回 True,则忽略异常,不再对异常进行处理

当 with as 操作上下文管理器时,就会在执行语句体之前,先执行上下文管理器的 __enter__() 方法,然后再执行语句体,最后执行 __exit__() 方法

构建上下文管理器,常见的有 2 种方式:

  • 基于类实现:只要一个类实现了__enter__() 和 __exit__() 方法,程序就可以使用 with as 语句来管理它。文件对象也实现了这两个方法,因此可以接受 with as 语句的管理
class Open:
    def __init__(self, filepath, mode='r', encoding='utf-8'):
        self.filepath = filepath
        self.mode = mode
        self.encoding = encoding

    def __enter__(self):
        # print('enter')
        self.f = open(self.filepath, mode=self.mode, encoding=self.encoding)
        return self.f

    def __exit__(self, exc_type, exc_val, exc_tb):
        # print('exit')
        self.f.close()
        return True

    def __getattr__(self, item):
        return getattr(self.f, item)

with Open('a.txt', 'w') as f:
    print(f)
    f.write('aaaaaa')
    f.wasdf  #抛出异常,交给__exit__处理
  • 基于生成器实现: file_manager() 就是一个生成器,当我们执行 with as 语句时,便会打开文件,并返回文件对象 f;当 with 语句执行完后,finally 中的关闭文件操作便会执行。另外可以看到,使用基于生成器的上下文管理器时,不再用定义 __enter__() 和 __exit__() 方法
from contextlib import contextmanager
@contextmanager
def file_manager(name, mode):
    try:
        f = open(name, mode)
        yield f
    finally:
        f.close()
       
with file_manager('a.txt', 'w') as f:
    f.write('hello world')

基于类的上下文管理器和基于生成器的上下文管理器,这两者在功能上是一致的。只不过,基于类的上下文管理器更加灵活,适用于大型的系统开发,而基于生成器的上下文管理器更加方便、简洁,适用于中小型程序。但是,无论使用哪一种,不用忘记在方法 __exit__() 或者是 finally 块中释放资源

常用模块

pickle模块

Python 中有个序列化过程叫作 pickle,能够实现任意对象与文本之间的相互转化,也可以实现任意对象与二进制之间的相互转化。也就是说,pickle 可以实现 Python 对象的存储及恢复

pickle 模块提供了以下函数:

  1. dumps():将 Python 中的对象序列化成二进制对象,并返回。其一般形式为dumps(obj, protocol=None, *, fix_imports=True)。其中,obj表示要转换的 Python 对象;protocol为pickle 的转码协议,取值为 0、1、2、3、4,其中 0、1、2 对应 Python 早期的版本,3 和 4 则对应 Python 3 版本及之后的版本。未指定情况下,默认为 3。其它参数则是为了兼容 Python 2 版本而保留的参数,Python 3 中可以忽略
import pickle
tup1 = ('I love Python', {1,2,3}, None)
p1 = pickle.dumps(tup1)
print(p1)
  1. loads():读取给定的二进制对象数据,并将其转换为 Python 对象。其一般形式为loads(data, *, fix_imports=True, encoding=‘ASCII’, errors=‘strict’)。其中,data 参数表示要转换的二进制对象,其它参数只是为了兼容 Python 2 版本而保留的,Python 3 中可以忽略。注意,在使用 loads() 函数将二进制对象反序列化成 Python 对象时,会自动识别转码协议,所以不需要将转码协议当作参数传入。并且,当待转换的二进制对象的字节数超过 pickle 的 Python 对象时,多余的字节将被忽略
import pickle
tup1 = ('I love Python', {1,2,3}, None)
p1 = pickle.dumps(tup1)
t2 = pickle.loads(p1)
print(t2)
  1. dump():将 Python 中的对象序列化成二进制对象,并写入文件。其一般形式为dump (obj, file,protocol=None, *, fix mports=True)。其中,obj为要转换的 Python 对象;file为转换到指定的二进制文件中,要求该文件必须是以"wb"的打开方式进行操作;protocol 和 dumps() 函数中 protocol 参数的含义完全相同;其他参数为了兼容以前 Python 2 版本而保留的参数,可以忽略
import pickle
tup1 = ('I love Python', {1,2,3}, None)
with open ("a.txt", 'wb') as f:
    pickle.dump(tup1, f)
  1. load():读取指定的序列化数据文件,并返回对象。其一般形式为load(file, *, fix_imports=True, encoding=‘ASCII’, errors=‘strict’)。其中,file 参数表示要转换的二进制对象文件(必须以 “rb” 的打开方式操作文件),其它参数只是为了兼容 Python 2 版本而保留的参数,可以忽略
import pickle
tup1 = ('I love Python', {1,2,3}, None)
with open ("a.txt", 'wb') as f:
    pickle.dump(tup1, f)
with open ("a.txt", 'rb') as f:
    print(pickle.load(f))
fileinput模块

Python 提供了 fileinput 模块,该模块中的 input() 函数能同时打开指定的多个文件,还可以逐个读取这些文件中的内容。其一般形式为
fileinput.input(files=“filename1, filename2, …”, inplace=False, backup=’’, bufsize=0, mode=‘r’, openhook=None)
此函数会返回一个 FileInput 对象,可以理解为是将多个指定文件合并之后的文件对象。其中

  • files:多个文件的路径列表
  • inplace:用于指定是否将标准输出的结果写回到文件,此参数默认值为 False
  • backup:用于指定备份文件的扩展名
  • bufsize:指定缓冲区的大小,默认为 0
  • mode:打开文件的格式,默认为 r(只读格式)
  • openhook:控制文件的打开方式,例如编码格式等

注意,和 open() 函数不同,input() 函数不能指定打开文件的编码格式,这意味着使用该函数读取的所有文件,除非以二进制方式进行读取,否则该文件编码格式都必须和当前操作系统默认的编码格式相同,不然 Python 解释器可能会提示 UnicodeDecodeError 错误。同时,fileinput 对象无需调用类似 read()、readline()、readlines() 这样的函数,直接通过 for 循环即可按次序读取多个文件中的数据

import fileinput
for line in fileinput.input(files=('my_file.txt', 'file.txt')):
    print(line)
fileinput.close()

除此之外,fileinput 模块还提供了很多使用的函数

  • fileinput.filename():返回当前正在读取的文件名称
  • fileinput.fileno():返回当前正在读取文件的文件描述符
  • fileinput.lineno():返回当前读取了多少行
  • fileinput.filelineno():返回当前正在读取的内容位于当前文件中的行号
  • fileinput.isfirstline():判断当前读取的内容在当前文件中是否位于第 1 行
  • fileinput.nextfile():关闭当前正在读取的文件,并开始读取下一个文件
  • fileinput.close():关闭 FileInput 对象
linecache模块

Python 提供了 linecache 模块,用来读取指定文件中的指定行。linecache 模块常用来读取 Python 源文件中的代码,它使用的是 UTF-8 编码格式来读取文件内容。这意味着,使用该模块读取的文件,其编码格式也必须为 UTF-8,否则要么读取出来的数据是乱码,要么直接读取失败(Python 解释器会报 SyntaxError 异常)

linecache 模块中常用的函数有:

  • linecache.getline(filename, lineno, module_globals=None):读取指定模块中指定文件的指定行(仅读取指定文件时,无需指定模块)。其中,filename 参数用来指定文件名,lineno 用来指定行号,module_globals 参数用来指定要读取的具体模块名。当指定文件以相对路径的方式传给 filename 参数时,该函数以按照 sys.path 规定的路径查找该文件
  • linecache.clearcache():如果程序某处不再需要之前使用 getline() 函数读取的数据,则可以使用该函数清空缓存
  • linecache.checkcache(filename=None):检查缓存的有效性,即如果使用 getline() 函数读取的数据,其实在本地已经被修改,而我们需要的是新的数据,此时就可以使用该函数检查缓存的是否为新的数据。注意,如果省略文件名,该函数将检测所有缓存数据的有效性
import linecache
import string

print(linecache.getline(string.__file__, 3))
print(linecache.getline('my_file.txt', 2))
pathlib模块

pathlib 模块中包含的是一些类,它们的继承关系如图所示
在这里插入图片描述

pathlib 模块的操作对象是各种操作系统中使用的路径

  • PurePath 类会将路径看做是一个普通的字符串,实现将多个指定的字符串拼接成适用于当前操作系统的路径格式,同时还可以判断任意两个路径是否相等,但并不会关心该路径是否真实有效。在使用 PurePath 类时,如果在 UNIX 或 Mac OS X 系统上使用 PurePath 创建对象,该类的构造方法实际返回的是 PurePosixPath 对象;反之,如果在 Windows 系统上使用 PurePath 创建对象,该类的构造方法返回的是 PureWindowsPath 对象。注意,通过PurePath 类构建的路径,虽然本质上是字符串类型,但与字符串并不完全一致,若要使其为字符串类型还需要使用 str()
  • PurePosixPath 和 PureWindowsPath 是 PurePath 的子类,前者用于操作 UNIX(包括 Mac OS X)风格的路径,后者用于操作 Windows 风格的路径
  • Path 类和以上 3 个类不同,它操作的路径一定是真实有效的。Path 类提供了判断路径是否真实存在的方法
  • PosixPath 和 WindowPath 是 Path 的子类,分别用于操作 Unix(Mac OS X)风格的路径和 Windows 风格的路径
from pathlib import *

print(PurePath('a','b','c')) # a\b\c
print(PurePath()) # .
print(PurePath('.')) # .
print(PurePath('C://','D://','my_file.txt')) # D:\my_file.txt
print(PurePath('C://./my_file.txt')) # C:\my_file.txt

# Unix风格的路径区分大小写
print(PurePosixPath('C://my_file.txt') == PurePosixPath('C://My_file.txt'))
# Windows风格的路径不区分大小写
print(PureWindowsPath('C://my_file.txt') == PureWindowsPath('C://My_file.txt'))

# 支持直接使用斜杠(/)作为多个字符串之间的连接符
path = PurePosixPath('C://')
print(path / 'my_file.txt')

PurePath类实例属性和实例方法

  • PurePath.parts:返回路径字符串中所包含的各部分
  • PurePath.drive:返回路径字符串中的驱动器盘符
  • PurePath.root:返回路径字符串中的根路径
  • PurePath.anchor:返回路径字符串中的盘符和根路径
  • PurePath.parents:返回当前路径的全部父路径
  • PurPath.parent:返回当前路径的上一级路径,相当于 parents[0] 的返回值
  • PurePath.name:返回当前路径中的文件名
  • PurePath.suffixes:返回当前路径中的文件所有后缀名
  • PurePath.suffix:返回当前路径中的文件后缀名。相当于 suffixes 属性返回的列表的最后一个元素
  • PurePath.stem:返回当前路径中的主文件名
  • PurePath.as_posix():将当前路径转换成 UNIX 风格的路径
  • PurePath.as_uri():将当前路径转换成 URL。只有绝对路径才能转换,否则将会引发 ValueError
  • PurePath.is_absolute():判断当前路径是否为绝对路径
  • PurePath.joinpath(*other):将多个路径连接在一起,作用类似于前面介绍的斜杠(/)连接符。
  • PurePath.match(pattern):判断当前路径是否匹配指定通配符
  • PurePath.relative_to(*other):获取当前路径中去除基准路径之后的结果
  • PurePath.with_name(name):将当前路径中的文件名替换成新文件名。如果当前路径中没有文件名,则会引发 ValueError
  • PurePath.with_suffix(suffix):将当前路径中的文件后缀名替换成新的后缀名。如果当前路径中没有后缀名,则会添加新的后缀名
os.path模块

相比 pathlib 模块,os.path 模块不仅提供了一些操作路径字符串的方法,还包含一些或者指定文件属性的一些方法

  • os.path.abspath(path):返回 path 的绝对路径
  • os.path.basename(path):获取 path 路径的基本名称,即 path 末尾到最后一个斜杠的位置之间的字符串
  • os.path.commonprefix(list):返回 list(多个路径)中,所有 path 共有的最长的路径
  • os.path.dirname(path):返回 path 路径中的目录部分
  • os.path.exists(path):判断 path 对应的文件是否存在,如果存在,返回 True;反之,返回 False。和 lexists() 的区别在于,exists()会自动判断失效的文件链接(类似 Windows 系统中文件的快捷方式),而 lexists() 却不会
  • os.path.lexists(path):判断路径是否存在,如果存在,则返回 True;反之,返回 False
  • os.path.expanduser(path):把 path 中包含的 “~” 和 “~user” 转换成用户目录
  • os.path.expandvars(path):根据环境变量的值替换 path 中包含的 “$name” 和 “${name}”
  • os.path.getatime(path):返回 path 所指文件的最近访问时间(浮点型秒数)
  • os.path.getmtime(path):返回文件的最近修改时间(单位为秒)
  • os.path.getctime(path):返回文件的创建时间(单位为秒,自 1970 年 1 月 1 日起(又称 Unix 时间))
  • os.path.getsize(path):返回文件大小,如果文件不存在就返回错误
  • os.path.isabs(path):判断是否为绝对路径
  • os.path.isfile(path):判断路径是否为文件
  • os.path.isdir(path):判断路径是否为目录
  • os.path.islink(path):判断路径是否为链接文件(类似 Windows 系统中的快捷方式)
  • os.path.ismount(path):判断路径是否为挂载点
  • os.path.join(path1[, path2[, …]]):把目录和文件名合成一个路径
  • os.path.normcase(path):转换 path 的大小写和斜杠
  • os.path.normpath(path):规范 path 字符串形式
  • os.path.realpath(path):返回 path 的真实路径
  • os.path.relpath(path[, start]):从 start 开始计算相对路径
  • os.path.samefile(path1, path2):判断目录或文件是否相同
  • os.path.sameopenfile(fp1, fp2):判断 fp1 和 fp2 是否指向同一文件
  • os.path.samestat(stat1, stat2):判断 stat1 和 stat2 是否指向同一个文件
  • os.path.split(path):把路径分割成 dirname 和 basename,返回一个元组
  • os.path.splitdrive(path):一般用在 windows 下,返回驱动器名和路径组成的元组
  • os.path.splitext(path):分割路径,返回路径名和文件扩展名的元组
  • os.path.splitunc(path):把路径分割为加载点与文件
  • os.path.walk(path, visit, arg):遍历path,进入每个目录都调用 visit 函数,visit 函数必须有 3 个参数(arg, dirname, names),dirname 表示当前目录的目录名,names 代表当前目录下的所有文件名,args 则为 walk 的第三个参数
  • os.path.supports_unicode_filenames:设置是否可以将任意 Unicode 字符串用作文件名
fnmatch模块

fnmatch 模块主要用于文件名称的匹配,其能力比简单的字符串匹配更强大,但比使用正则表达式相比稍弱。fnmatch 模块中常用的函数有

  • fnmatch.filter(names, pattern):对 names 列表进行过滤,返回 names 列表中匹配 pattern 的文件名组成的子集合
  • fnmatch.fnmatch(filename, pattern):判断 filename 文件名,是否和指定 pattern 字符串匹配
  • fnmatch.fnmatchcase(filename, pattern):和 fnmatch() 函数功能大致相同,只是该函数区分大小写
    +fnmatch.translate(pattern):将一个 UNIX shell 风格的 pattern 字符串,转换为正则表达式

fnmatch 模块匹配文件名的模式使用的就是 UNIX shell 风格,其支持使用如下几个通配符:

  • *:可匹配任意个任意字符
  • ?:可匹配一个任意字符
  • [字符序列]:可匹配中括号里字符序列中的任意字符。该字符序列也支持中画线表示法。比如 [a-c] 可代表 a、b 和 c 字符中任意一个
  • [!字符序列]:可匹配不在中括号里字符序列中的任意字符
import fnmatch

print(fnmatch.filter(['dlsf', 'ewro.txt', 'te.py', 'youe.py'], '*.txt'))

for file in ['word.doc','index.py','my_file.txt']:
    if fnmatch.fnmatch(file,'*.txt'):
        print(file)

print([addr for addr in ['word.doc','index.py','my_file.txt','a.TXT'] if fnmatch.fnmatchcase(addr, '*.txt')])

print(fnmatch.translate('a*b.txt'))
os模块

Python的标准库中的os模块包含普遍的操作系统功能,允许一个程序在编写后不需要任何改动,也不会发生任何问题,就可以在Linux和Windows下运行

os模块常用属性函数如下

  • os.sep:可以取代操作系统特定的路径分隔符。windows下为 “\”
  • os.name:字符串指示你正在使用的平台。比如对于Windows,它是’nt’,而对于Linux/Unix用户,它是’posix’
  • os.linesep:字符串给出当前平台使用的行终止符。例如,Windows使用’\r\n’,Linux使用’\n’而Mac使用’\r’
  • os.curdir:返回当前目录(’.’)
  • os.getcwd():函数得到当前工作目录,即当前Python脚本工作的目录路径
  • os.getenv():获取一个环境变量,如果没有返回none
  • os.putenv(key, value):设置一个环境变量值
  • os.listdir(path):返回指定目录下的所有文件和目录名
  • os.mkdir(path):创建一个目录,且该目录的父目录必须是已存在的
  • os.makedirs(path):创建一系列目录,该目录的父目录不存在也可,会立即创建
  • os.remove(path):函数用来删除一个文件,不能删除文件夹
  • os.rmdir():删除一个目录,只能删除空目录.如果删除的目录不存在,则会报错
  • os.system(command):函数用来运行shell命令
  • os.chdir(dirname):改变工作目录到dirname
tempfile模块

tempfile 模块专门用于创建临时文件和临时目录,临时文件和临时目录在程序关闭时会自动销毁。tempfile 模块可以在 UNIX 平台上运行良好,也可以在 Windows 平台上运行良好。tempfile 模块中常用的函数有

  • tempfile.TemporaryFile(mode=‘w+b’, buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None):创建临时文件。该函数返回一个类文件对象,也就是支持文件 I/O
  • tempfile.NamedTemporaryFile(mode=‘w+b’, buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None, delete=True):创建临时文件。该函数的功能与上一个函数的功能大致相同,只是它生成的临时文件在文件系统中有文件名
  • tempfile.SpooledTemporaryFile(max_size=0, mode=‘w+b’, buffering=None, encoding=None, newline=None, suffix=None, prefix=None, dir=None):创建临时文件。与 TemporaryFile 函数相比,当程序向该临时文件输出数据时,会先输出到内存中,直到超过 max_size 才会真正输出到物理磁盘中
  • tempfile.TemporaryDirectory(suffix=None, prefix=None, dir=None):生成临时目录
  • tempfile.gettempdir():获取系统的临时目录
  • tempfile.gettempdirb():与 gettempdir() 相同,只是该函数返回字节串
  • tempfile.gettempprefix():返回用于生成临时文件的前缀名
  • tempfile.gettempprefixb():与 gettempprefix() 相同,只是该函数返回字节串

tempfile 模块还提供了 tempfile.mkstemp() 和 tempfile.mkdtemp() 两个低级别的函数。上面介绍的 4 个用于创建临时文件和临时目录的函数都是高级别的函数,高级别的函数支持自动清理,而且可以与 with 语句一起使用,而这两个低级别的函数则不支持,因此一般推荐使用高级别的函数来创建临时文件和临时目录。此外,tempfile 模块还提供了 tempfile.tempdir 属性,通过对该属性赋值可以改变系统的临时目录

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值