User:Xyy23330121/Python/文件系统

来自维基学院


模块 os 提供了许多有效的操作系统工具。本页省略掉其中一些操作,转而注重于操作系统中、对文件系统的操作。比如删除、复制、重命名(移动)、新建等。

除此之外,Python 还额外提供了模块 shutil 用于进行一些高阶文件操作。在一项操作可以用 shutil 中的函数完成时,用 shutil 提供的函数一般更快。

文件路径[编辑 | 编辑源代码]

提示
阅读 Python 文档时会发现,文件路径也支持用 bytes 来存储[1]。但若要详细询问以何种格式或编码来用 bytes 存储文件路径,就没有相关的说明了。我们仅能找到类似 os.fsdecode() 和 os.fsencode() 的转换函数[1]以及在 os.getcwdb() 函数中找到的“在Windows上,用UTF-8编码”的说明[2]。认为 bytes 路径的跨平台支持可能不完善。
反正可以转化为字符串,那不妨只用字符串比较好。

形如 C:\Program Files\Python 的,被称为是文件路径。在 Python 中,文件路径通常是由字符串存储的。比如:

path_str = r"C:\Program Files\Python"  #使用“原始字符串”

Python 也支持使用抽象基类 os.PathLike 的子类来存储路径。

os.PathLike[编辑 | 编辑源代码]

当一个类具有 __fspath__ 方法时,它就被视为是 os.PathLike 的子类。

__fspath__ 方法应该返回一个表示路径的字符串,比如:

class Path:
    ...
    def __fspath__(self):
        return r"C:\Program Files\Python"

传入路径参数时,可以传入路径字符串,也可以传入 os.PathLike 的子类实例。

os.fspath(path)[编辑 | 编辑源代码]

本函数输入一个路径参数,然后返回字符串形式的路径。我们看以下示例:

class Path:
    def __fspath__(self): return r"C:\Program Files\Python"

p = Path()
print(os.fspath(p)) #输出:C:\Program Files\Python

绝对路径与相对路径[编辑 | 编辑源代码]

形如下面的,被称为是绝对路径。

path = r"C:\Program Files\Python"

绝对路径比较好理解,这里主要描述相对路径。

工作路径[编辑 | 编辑源代码]

命令行程序,比如 Windows 的 cmd、PowerShell,以及 linux 的 terminal,都是有“当前工作目录”的。这是早期计算机系统,没有图形文件管理器时,用命令行程序来管理文件所需的功能。

以 PowerShell 为例,如果运行:

PS D:\test> & python.exe C:\test.py

并从 test.py 中输出“当前工作路径”。我们会发现当前工作路径为:D:\test,即调用 Python 时,PowerShell 的工作路径。而非 C:\ ,即 test.py 所在的路径。使用相对路径时要注意这一点。

相对路径与工作路径[编辑 | 编辑源代码]

相对路径是相对于当前工作路径而言的。我们同样以刚才的例子,如果在 test.py 中,用:

path = "Python"

来表示路径,则在上面的运行中,path 代表的是 D:\test\Python

输出与更改工作路径[编辑 | 编辑源代码]

os.getcwd()[编辑 | 编辑源代码]

os.getcwd() 会输出当前工作路径的字符串。

os.chdir(path)[编辑 | 编辑源代码]

os.chdir(path) 会把工作路径设为 path 所示的路径。

path 可以为表示路径的字符串,也可以为上面所述的、os.PathLike 的子类。

特殊的相对路径[编辑 | 编辑源代码]

特别的,. 表示当前路径,而 .. 表示上一级文件夹。

比如以下的情况:

folder/
    test.py
    MyModule/
        __init__.py
        SubModule/
            __init__.py

为了说明简单起见,我们把工作路径设到 SubModule 文件夹中,然后看以下代码的输出:

print(os.listdir('..'))           #输出:['SubModule', '__init__.py'],说明该路径代表 MyModule 文件夹。
print(os.listdir('.'))            #输出:['__init__.py'],说明该路径代表 SubModule 文件夹。
print(os.listdir(r'..\..'))       #输出:['MyModule', 'test.py'],说明该路径代表 folder 文件夹。
print(os.listdir(r'..\.\SubModule\..\..')) #输出:['MyModule', 'test.py'],说明该路径代表 folder 文件夹。

其中使用的函数,在本章后面会讲到。

路径分隔符[编辑 | 编辑源代码]

在操作路径时,有时会出现不同系统路径分隔符不同的情况。比如,我们在路径 folder 下创建了文件夹 sub,然后想操作 sub 中的内容。使用 Windows 系统的程序员,很容易把路径写为:

folder = ...
sub = ...
path = folder "\\" sub

但是,这在使用"/"为路径分隔符的系统中,是不适用的。此时,可以用模块 os 和 os.path 中提供的内容来解决这个问题。

路径分隔符:os.sep[编辑 | 编辑源代码]

使用以下方法可以避免出现上面的问题:

import os

folder = ...
sub = ...
path = folder os.sep sub

os.sep会给出当前系统的路径分隔符。其它的、文件系统所使用的字符串,见下面的表格。

此类型的常量,许多在 os 模块中和 os.path 模块中都会有。

模块 系统 说明
os 模块 os.path 模块 POSIX Windows
os.curdir os.path.curdir '.' 系统用于表示当前文件夹的常量字符串。
os.pardir os.path.pardir '..' 系统用于表示父文件夹的常量字符串。
os.sep os.path.sep '/' '\\' 系统路径分隔符。
os.altsep os.path.altsep None '/' 系统路径分隔符的替代字符。
os.extsep os.path.extsep '.' 系统用于分割文件名与拓展名的字符。
os.pathsep os.path.pathsep ':' ';' 系统用于分隔搜索路径(如 PATH)中不同部分的字符
os.devnull os.path.devnull '/dev/null' 'nul' 空设备的文件路径

拼接路径:os.path.join(path, *paths)[编辑 | 编辑源代码]

也可以用这些模块中,操作路径的函数来解决问题:

folder = ...
sub = ...

import os.path
path = os.path.join(folder, sub)

文件操作[编辑 | 编辑源代码]

简单判断[编辑 | 编辑源代码]

os.path.exists(path)[编辑 | 编辑源代码]

path 为一个路径。如果 path 所示的内容存在,则返回 True。特别的,对于失效的符号链接,返回 False

除非特殊说明,以下函数的 path 参数均应传入路径。

os.path.lexists(path)[编辑 | 编辑源代码]

类似 exists,但对于失效的符号链接,返回 True

os.path.isfile(path)[编辑 | 编辑源代码]

如果 path 所示的内容存在,且是一个文件,则返回 True。本方法会跟踪符号链接,因此,如果 path 所示的符号链接指向一个文件,也会返回 True

os.path.isdir(path)[编辑 | 编辑源代码]

类似 os.path.isfile,但检查的是文件夹。

os.path.islink(path)[编辑 | 编辑源代码]

如果 path 所示的内容存在,且是符号链接,则返回 True

os.path.isjunction(path)[编辑 | 编辑源代码]

如果 path 所示的内容存在,且是 junction,则返回 True。junction 是 NTFS 上独有的一个类似符号链接的内容。

列出文件名:os.listdir(path = '.')[编辑 | 编辑源代码]

提示
由于“相对路径”的规定,本函数省略 path 后,可以直接用于遍历工作路径中的文件和文件夹列表。

返回 path 中,所有子文件夹和文件的名称组成的列表。

迭代文件:os.scandir(path='.')[编辑 | 编辑源代码]

类似 os.listdir(),但返回的并非是列表,而是一个特殊的迭代器。该迭代器中的元素为 os.DirEntry 类型。这种类型的元素包含了文件类型或文件属性信息,因此,如果代码需要查询文件类型或文件属性,用 scandir 而非 listdir 会提升性能。

迭代器的迭代顺序可能是任意顺序,而非浏览文件夹时常有的“字母顺序”或“更改时间顺序”等。

scandir.close()[编辑 | 编辑源代码]

对于由 os.scandir 生成的迭代器 scandir,该序列包含一个方法 close

scandir.close() 会关闭该迭代器,并释放占用的资源。

尽管该方法在迭代结束或出错时会自动调用。但最好还是在迭代结束后手动调用一遍该方法,或者使用 with 语句。

os.DirEntry[编辑 | 编辑源代码]

os.scandir 生成的、迭代器中的迭代元素。该元素有以下属性和方法:

name[编辑 | 编辑源代码]

文件或文件夹的名称。

path[编辑 | 编辑源代码]

文件或文件夹的路径。如果 os.scandir 的参数为绝对路径,则这里为绝对路径;如果 os.scandir 的参数为相对路径或空缺,则这里为相对路径。

相对路径是相对于使用 os.scandir 时的工作路径的。

is_dir(*, follow_symlinks=True)[编辑 | 编辑源代码]

如果是文件夹,或是指向文件夹的符号链接,则返回 True。反之,返回 False

follow_symlinksFalse,则该迭代元素指向符号链接时,也会返回 False

is_file(*, follow_symlinks=True)[编辑 | 编辑源代码]

类似is_dir(),如果是文件,则返回 True

stat(*, follow_symlinks=True)[编辑 | 编辑源代码]

类似is_dir(),但返回详细的属性。属性将以 stat_result 类型的形式返回。

关于 stat_result 的详细信息,参见下面的章节。

inode()[编辑 | 编辑源代码]

返回迭代元素所对应内容的索引节点号。

is_symlink()[编辑 | 编辑源代码]

如果是符号链接,返回 True。反之,返回 False

is_junction()[编辑 | 编辑源代码]

如果是junction,则返回 True。反之,返回 False

迭代文件树:os.walk(top)[编辑 | 编辑源代码]

os.walk(top, topdown=True, onerror=None, followlinks=False)

返回一个可迭代对象。对 top 中的每个文件夹,都会在可迭代对象中增加元素 (dirpath, dirnames, filenames)

其中,dirpath 是文件夹路径,dirnames 是文件夹中,子文件夹的名称列表,filenames 是文件夹中的文件名称列表。比如以下的情况:

folder/
    test.py
    MyModule/
        __init__.py
        SubModule/
            __init__.py

如果把工作路径设到 folder 所在的路径,再用 os.walk('folder'),则会有形如以下的元素被添加到可迭代对象中:

('folder', ['MyModule'], ['test.py'])
('folder\\MyModule', ['SubModule'], ['__init__.py'])
('folder\\MyModule\\SubModule', [], ['__init__.py'])

topdownTrue,则增加元素的方式是递归地。在迭代时,它会先生成包含 top 的三元组。下一次迭代时,存储第一次迭代时得到的三元组,再按其中 dirnames 里的子文件夹进行迭代,生成来自这些子文件夹的三元组。以此类推。

特别的,此时,在迭代过程中,可以直接对三元组中的 dirname ,使用列表的方法来进行修改,以控制之后的迭代顺序与内容。

topdownFalse。则会先生成父文件夹中、所有子文件夹的三元组,再生成父文件夹。此时,更改 dirname 的内容对迭代没有影响。可以用此方法来从后往前删除空文件夹。

onerror 为一个错误处理函数。该函数输入一个 OSError 实例。在不输入此函数时,os.walk 默认会忽略它调用 os.scandir 时产生的错误。若输入了此函数,读者可以通过自定义该函数,决定出错时是报错并停止、只输出错误信息还是忽略错误。

top 与输出[编辑 | 编辑源代码]

输入 top 的内容与函数的结果有关。我们依旧是上面的例子,运行:

for obj in os.walk(r"folder\."):
	print(obj)

输出为:

('folder\\.', ['MyModule'], ['test.py'])
('folder\\.\\MyModule', ['SubModule'], ['__init__.py'])
('folder\\.\\MyModule\\SubModule', [], ['__init__.py'])

特别的,向 top 传入 "."".." 等来选择工作路径,或工作路径的上级路径,也是有效的。如果工作路径在运行过程中可能会改变,最好还是对 top 使用绝对路径。

创建文件夹:os.mkdir(path)[编辑 | 编辑源代码]

os.mkdir(path, mode=0o777, *, dir_fd=None)

本函数会创建路径为 path 的文件夹。但只创建“一层”:比如向 path 传入 C:\folder\folder,而 C:\folder 不存在时,会报错 FileNotFoundError

如果 path 已经存在,则会报错 FileExistsError

mode 参数对各个不同系统有区别,为了代码的可移植性,最好不要进行自定义。dir_fd 是指向目录 dirpath 的文件描述符,在一些平台上不被支持,因此也不多赘述。如果读者需要了解关于 dir_fd 的内容,参见 python文档

os.mkdirs(name, mode=0o777, exist_ok=False)[编辑 | 编辑源代码]

本函数会递归地创建路径为 name 的文件夹。比如向 name 传入 C:\folder\folder,而 C:\folder 不存在时,它会调用 os.mkdirs("C:\folder", mode)

exist_okFalse,当 name 所示路径已经存在时,会报错 FileExistsError

mode 参数对各个不同系统有区别。

删除文件夹:os.rmdir(path, *, dir_fd=None)[编辑 | 编辑源代码]

本函数会删除空文件夹。仅删除一层:比如向 path 传入 C:\folder\folder 时,仅删除 C:\folder\folder,而保留 C:\folder

如果目录不存在,则报错 FileNotFoundError。如果目录不为空,则报错 OSError

os.removedirs(name)[编辑 | 编辑源代码]

本函数会删除空文件夹。但不止删除一层:比如向 name 传入 C:\folder\folder 时,会先删除 C:\folder\folder,再检查 C:\folder 是否是空文件夹,如果是,则继续进行删除。直到某一层不是空文件夹为止。

如果无法成功删除 name 所示的文件夹,则会报错 OSError

删除文件:os.remove(path, *, dir_fd=None)[编辑 | 编辑源代码]

本函数仅用于删除文件。

如果 path 是目录,则会报错 OSError。如果 path 不存在,则会报错 FileNotFoundError

还有一个函数 os.unlink 和本函数完全一致。unlink 是其传统的 Unix 名称。

删除:shutil.rmtree(path)[编辑 | 编辑源代码]

提示
在阅读 Python 文档时,如果出现中文翻译不容易读懂时,请一定去查阅英文原文——十有八九是翻译问题。在 shutil 模块中已经发现许多翻译问题。 如果发现翻译问题,读者可以前往Python 中文文档的 Github 反馈界面对于一些翻译问题提供反馈。

shutil.rmtree(path, ignore_errors=False, *, onexc=None, dir_fd=None)

此函数会删除 path 所示文件夹以及其中的所有内容。path 必须是文件夹。

如果 ignore_errorsTrue,则在删除失败时,不会进行报错。

onexc 参数是用于处理异常的函数。只有 ignore_errorsFalse 时,才会尝试让 onexc 来处理异常。

onexc 参数[编辑 | 编辑源代码]

如果传入了 onexc 参数,并且在删除时引发了异常,则会将异常信息发送给该参数,并由该参数进行处理。它会按顺序传入三个信息:

  1. function: 删除过程中,引发异常的函数。
    它依赖于运行的平台和实现。
  2. path:删除过程中,function 被传入的路径。
  3. excinfo:出错时,异常的实例。

如果在运行 onexc 函数时出错,则不会再把异常捕获并发送给 onexc,而是直接进行处理。

Python 的文档提供了以下示例:

删除只读文件也会导致报错。通过以下的方式,可以删除只读文件。

import os, stat
import shutil

def remove_readonly(func, path, _):
    "Clear the readonly bit and reattempt the removal"
    os.chmod(path, stat.S_IWRITE)
    func(path)

shutil.rmtree(directory, onexc=remove_readonly)

复制文件[编辑 | 编辑源代码]

shutil.copyfile(src, dst, *, follow_symlinks=True)[编辑 | 编辑源代码]

srcdst 都是路径。本函数会将 src 中的内容复制到 dst。比如以下示例:

import os, stat
import shutil

shutil.copyfile("测试.txt", "测试(副本).txt")

该实例运行的结果是,新建“测试(副本).txt”,再把“测试.txt”中的全部内容复制到“测试(副本).txt”中。

如果 dst 是已经存在的文件,则会替换掉该文件。如果 srcdst 指向同一个文件,则会引发错误 shutil.SameFileError

follow_symlinks 用于决定 src 是文件链接时的处理方式。如果 follow_symlinksFalsesrc 为符号链接,则复制的结果是一个新的符号链接,而不是 src 所指向的文件内容。

在复制完成后,本函数会返回 dst

shutil.copy(src, dst, *, follow_symlinks=True)[编辑 | 编辑源代码]

shutil.copyfile 几乎一致。只有一点不同:

如果 dst 指向一个已存在的文件夹,则会在 dst 中按 src 所示的文件名新建文件,再复制数据。

shutil.copy2(src, dst, *, follow_symlinks=True)[编辑 | 编辑源代码]

类似 shutil.copyfile ,但是会保留文件的元数据(比如修改时间等)。

保留元数据的功能并非所有平台都可以使用,读者可以按照 该文档中的描述 检查各个平台能否保留文件的相应元数据。本函数会尽可能地保留元数据,在无法保留元数据时,也不会报错。

shutil.copytree(src, dst)[编辑 | 编辑源代码]

shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)

该函数用于直接复制整个文件夹以及其中的内容。它会把文件夹 src 中的所有内容复制到文件夹 dst 中。

具体来讲,它会先用类似 os.mkdirs 函数的方式创建 dst 目录。如果 dst 目录已存在,则会报错 FileExistsError 并停止拷贝。

如果 dir_exist_okTrue,则即便 dst 目录已存在,也不会报错,而是继续拷贝。

copy_function[编辑 | 编辑源代码]

copy_function 决定了本函数会用什么函数来复制这些文件。默认使用 shutil.copy2 来复制这些文件。

上面所示的 shutil.copyfileshutil.copyshutil.copy2 都可以使用。如果要自定义该函数,则该函数必须能传入三个参数:

  1. src 复制文件的来源
  2. dst 复制到的位置
  3. follow_symlinks 是否追踪符号链接
symlinks[编辑 | 编辑源代码]

本函数中,如果 symlinksTrue。则复制函数中的参数 follow_symlinksFalse

ignore_dangling_symlinks[编辑 | 编辑源代码]

symlinksTrue,而符号链接指向的文件不存在时,本函数会在拷贝完成后报错 shutil.Errorshutil.Error 是一个包含该函数中出现的所有异常组成的异常组,它会在复制结束后被引发。

ignore[编辑 | 编辑源代码]

ignore 应传入一个决定哪些文件 / 文件夹不被复制的函数。

备注
如果要掌握完整的流程,请查阅 源代码

如果 ignore 不为 None,本函数的复制流程经简化后大致如下:

  1. src 中所有文件和文件夹的名称添加到“代办列表”
  2. src 和“代办列表”传入 ignore 函数,得到“忽略列表”
  3. 遍历“代办列表”:
    1. 如果在“忽略列表”中,则忽略。
    2. 其余的,如果是文件夹,则把该文件夹再次传入 shutil.copytree 中。
    3. 其余的,用 copy_function 来复制文件。

于是,对于被复制的一个文件夹 folderignore 函数会被分别传入:

  1. os.fspath(folder),即 folder 的字符串形式。
  2. os.listdir(folder),即 folder 路径中的内容。

它应该返回 os.listdir(folder) 中元素组成的一个列表(或集合等,可以用比较运算符 in 的类型),包含不会被复制的子文件夹名称和子文件名称。

shutil.ignore_patterns(*patterns)[编辑 | 编辑源代码]

可以用这个函数创建 ignore 函数。

该函数返回的对象,会把符合 *patterns 的所有子文件名、子文件夹名都添加到“忽略列表”中。匹配是按照 模块 fnmatch 的规则进行匹配的。

移动/重命名[编辑 | 编辑源代码]

os.rename(src, dst, *, src_dir_fd=None, dst_dir_fd=None)[编辑 | 编辑源代码]

移动 src 所示的文件或文件夹,使其路径变为 dst

注意,dst 只能被创建“一层”,其父文件夹必须存在。如果对以下所示的文件树:

folder/
    a.txt

将工作路径设到 folder,然后执行 os.rename("a.txt",r"a\a.txt") 时,会报错。因为文件夹 folder\a 是不存在的。

对于比如 dst 已经存在的情况。该函数在不同系统中的具体表现是不同的。Python 文档列举了两个系统的以下情况:

状况 Windows Unix
dst 已经存在 src 是文件而 dst 是目录 报错:
FileExi
stsError
报错 ISADirectoryError
两者都
是目录
dst 是空目录 src 中的内容被移动到 dst 中
dst 是非空目录 报错 OSError
两者都
是文件
用户有权限 替换掉 dst 的内容
src 和 dst 在不同文件系统上 可能会失败,此时建议使用 shutil.move()

os.renames(old, new)[编辑 | 编辑源代码]

本函数和 os.rename 的关系,类似 os.mkdiros.mkdirs 的关系。

如果新路径 new 所需要的父文件夹不存在,则会先把父文件夹创建完毕。

在移动完成后,将调用 removedirs 删除旧路径中的空文件夹。

os.replace(src, dst, *, src_dir_fd=None, dst_dir_fd=None)[编辑 | 编辑源代码]

类似 os.rename。但是当 dst 存在且为文件时,会对其进行替换。

shutil.move(src, dst, copy_function=copy2)[编辑 | 编辑源代码]

先将 src 所示文件或文件夹用 copy_function 复制到 dst,再把 src 删除。最后,返回 dst

如果 dst 指向一个已存在的文件夹。那么,在复制时,会在 dst 中按 src 所示的文件名新建文件并进行复制。

如果 dst 已存在但不是文件夹,则按照 os.rename 的覆写规则决定是覆写还是报错。

如果 srcdst 使用相同的文件系统,则不会使用 copy_function,而是改为直接调用 os.rename

os.stat_result 的部分属性
属性名 解释
Unix Windows
st_mode 文件模式:文件类型和权限位
st_ino 索引节点号    inode number 文件索引号[3]
st_dev 文件所在设备的设备标识符
st_nlink 硬链接的数量
st_uid 文件所有者的用户 ID
st_gid 文件所有者的用户组 ID
st_size 文件大小,以字节(B)为单位的整数
时间戳(纪元时间)
st_atime 最近访问时间,以秒为单位
st_atime_ns 最近访问时间,以纳秒为单位的整数
st_mtime 最近修改时间,以秒为单位
st_mtime_ns 最近修改时间,以纳秒为单位的整数
st_ctime 元数据的最近修改时间 不建议使用:  文件创建时间。
st_ctime_ns 类似 st_ctime,但是以纳秒为单位
st_birthtime 文件创建时间,以秒为单位
该属性并不总是可用,使用时可能报错 AttributeError
st_birthtime_ns 类似 st_birthtime,但是以纳秒为单位

查看文件元信息[编辑 | 编辑源代码]

我们有以下方式查看文件元信息。

os.stat(path, *, dir_fd=None, follow_symlinks=True)[编辑 | 编辑源代码]

对于文件 path,返回一个包含文件元信息的对象 os.stat_result

os.stat_result 的属性见右边。

os.stat_result[编辑 | 编辑源代码]

除右侧的属性外,还可以用 stat 模块 中提供的一些方式去读取这个结果。这里不多赘述。

os.path.getatime(path)[编辑 | 编辑源代码]

返回最后访问时间,为纪元秒数的浮点数。如果该文件不存在或不可访问,则报错 OSError

os.path.getmtime(path)[编辑 | 编辑源代码]

返回最后修改时间,为纪元秒数的浮点数。如果该文件不存在或不可访问,则报错 OSError

os.path.getctime(path)[编辑 | 编辑源代码]

返回元数据最后修改时间,为纪元秒数的浮点数。如果该文件不存在或不可访问,则报错 OSError

在 Windows 上,返回创建时间,为纪元秒数的浮点数。

os.path.getsize(path)[编辑 | 编辑源代码]

返回文件大小,以字节为单位的整数。如果该文件不存在或不可访问,则报错 OSError

操作文件元信息[编辑 | 编辑源代码]

os.utime(path, times=None, *, [ns, ]dir_fd=None, follow_symlinks=True)[编辑 | 编辑源代码]

设置文件的“最近访问时间”和“最近修改时间”。如果不指定时间,则以当前时间(纳秒)来进行设置。

如果传入 ns,则应传入一个(访问时间, 修改时间)的元组。其中每个元素是以纳秒为单位的整数(纪元时间)。

如果传入 times,则应传入一个(访问时间, 修改时间)的元组。其中每个元素是以秒为单位的整数(纪元时间)。

同时传入 nstimes 会出错。

shutil.copymode(src, dst, *, follow_symlinks=True)[编辑 | 编辑源代码]

设置 dst 的权限位,使其和 src 的权限位一致。

shutil.copystat(src, dst, *, follow_symlinks=True)[编辑 | 编辑源代码]

设置 dst 的权限位、最近访问时间、最近修改时间以及旗标,使其和 src 的元数据一致。

更多路径操作[编辑 | 编辑源代码]

标准化路径[编辑 | 编辑源代码]

绝对路径:os.path.abspath(path)[编辑 | 编辑源代码]

对于给出的路径 path,返回其标准化的绝对路径。

“标准化”指的是形如 folder\\foo\\.. 的内容会被简化为等效的 folder

判断绝对路径:os.path.isabs(path)[编辑 | 编辑源代码]

如果路径是绝对路径,返回 True

在 Unix 上,这代表路径以斜杠开头。而在 Windows 上,路径可以为:

  1. 驱动器号+冒号开头,比如 C:C:\Program Files
  2. 反斜杠开头,比如 \Program Files
  3. 双反斜杠开头(对于本地网络共享的文件使用的UNC路径),比如 \\host\sharename

其它类似的判断,还有判断挂载点的 os.path.ismount(path)[4] 和判断 Windows Dev 驱动器的 os.path.isdevdrive(path)[5]。具体请参见相关文档。

标准化路径:os.path.normpath(path)[编辑 | 编辑源代码]

对于给出的路径 path,返回其标准化的路径。

去除符号链接:os.path.realpath(path, *, strict=False)[编辑 | 编辑源代码]

消除路径中的符号链接,返回指向文件的真实路径。

分割[编辑 | 编辑源代码]

对路径的分割操作都是字符串操作。

os.path.basename(path)[编辑 | 编辑源代码]

返回路径所对应的文件名 / 文件夹名。我们有以下示例:

import os.path
path = "C:\\Program Files"
print(os.path.basename(path)) #输出:Program Files

os.path.dirname(path)[编辑 | 编辑源代码]

返回路径中文件名 / 文件夹名以外的部分。该部分的结尾不会有分隔符。我们有以下示例:

import os.path
path = "C:\\Program Files"
print(os.path.basename(path)) #输出:C:

os.path.split(path)[编辑 | 编辑源代码]

返回 (os.path.dirname(path), os.path.basename(path))

其它类似的分割,还有 os.path.splitdrive(path)[6]os.path.splitroot(path)[7]os.path.splitext(path)[8]。这里不多赘述。

os.path.commonpath(paths)[编辑 | 编辑源代码]

对于包含多个路径的序列 paths,输出其公共的最小父文件夹。我们有以下示例:

import os.path
paths = ["C:\\Program Files", "C:\\Program Files (x86)"]
print(os.path.commonpath(paths)) #输出:"C:\\"

os.path.commonprefix(paths)[编辑 | 编辑源代码]

对于包含多个路径的序列 paths,输出其公共的“前缀”。我们有以下示例:

import os.path
paths = ["C:\\Program Files", "C:\\ProgramData"]
print(os.path.commonpath(paths)) #输出:"C:\\Program"

环境变量[编辑 | 编辑源代码]

用户目录:os.path.expanduser(path)[编辑 | 编辑源代码]

将参数中开头部分的 ~~user 替换为当前用户的用户目录,并返回替换的结果。

环境变量:os.path.expandvars(path)[编辑 | 编辑源代码]

输入带有环境变量的路径,返回环境变量展开后的路径。对于 Windows,环境路径可以参照以下页面:

  1. 微软关于环境变量的文档
  2. Windows 的环境变量与默认值

本函数会展开 path 中形如 ${name} 的部分。对于 Windows,还会展开形如 %name% 的部分。其中,name 指的是环境变量名称。

os.path.supports_unicode_filenames[编辑 | 编辑源代码]

如果系统支持使用任意 unicode 字符(分隔符等除外)作为文件名,则此项为 True

归档[编辑 | 编辑源代码]

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]]) shutil.get_archive_formats() shutil.register_archive_format(name, function[, extra_args[, description]]) shutil.unregister_archive_format(name) shutil.unpack_archive(filename[, extract_dir[, format[, filter]]]) shutil.register_unpack_format(name, extensions, function[, extra_args[, description]]) shutil.unregister_unpack_format(name) shutil.get_unpack_formats()

shutil.disk_usage(path) shutil.chown(path, user=None, group=None) shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)

參考文獻[编辑 | 编辑源代码]