Python的pathlib模块:驯服文件系统

原文链接:https://realpython.com/python-pathlib/#creating-empty-files

by Geir Arne Hjelle Apr 17, 2023

目录

  • 将路径表示为字符串的隐患
  • 用Python的pathlib把路径实例化
    • 使用Path类的方法
    • 传入字符串
    • 拼接路径
  • 用Path进行文件系统操作
    • 获取路径的各个部分
    • 读写文件
    • 重命名文件
    • 复制文件
    • 移动、删除文件
    • 创建空文件
  • Python pathlib案例
    • 统计文件个数
    • 显示文件夹树状结构
    • 找到最近修改的文件
    • 创建独一无二的文件名
  • 结语

对Python开发者来说,和文件打交道、和文件系统互动都是稀疏平常的事。有时是仅仅读写文件,而有时则更复杂。也许你需要在一个给定文件夹里列出给定类别的所有文件、找到给定文件的父级文件夹或是创建一个先前不存在的独一无二的文件名。这时就可以用 pathlib

pathlib 模块在Python标准库里,能帮助你应对上述挑战。它集成了诸多必要功能,你可以方便地调用 Path 对象的方法和属性来达成这些功能。

在本教程中,你将学到:

  • 在Python里处理文件和文件夹的路径
  • 以多种方式实例化一个 Path 对象
  • 使用 pathlib读写文件
  • 谨慎地复制、移动和删除文件
  • 操作路径和底层文件系统
  • 获取路径的各个部分

你也将在本教程里学到一大堆代码案例,你完全可以把它们用在你的日常文件操作中。比如,你将深入了解统计文件个数、找到文件夹中最近修改的文件以及创建独一无二的文件名。

pathlib 能提供这么多方法和属性是极好的,但是匆匆忙忙地背下来却很困难。这时一个小抄就显得很有必要啦,点击下方链接获取你的小抄:

Free Download: Click here to claim your pathlib cheat sheet so you can tame the file system with Python.

将路径表示为字符串的隐患

有了Python的 pathlib ,你终于不用那么头疼了。它灵活的 Path 类有着直观的语义。先别急着了解这个类,看看 pathlib 诞生前,Python开发者们是怎么处理路径的。

传统方式是,Python用普通的 text strings (文本字符串)来表示文件路径。然而,由于路径所代表的含义不仅仅是一个字符串,与之相关的重要功能就在标准库里散得到处都是,包括os, glob, 和 shutil

比如,下面这个代码块将文件移动在一个子文件夹里:

import glob
import os
import shutil

for file_name in glob.glob("*.txt"):
    new_path = os.path.join("archive", file_name)
    shutil.move(file_name, new_path)

就为了把所有的文本文件移动到一个归档文件夹里,你需要三个 import statements (import 语句)。

Python的 pathlib 提供了一个 Path 类,在不同的操作系统里用法都相同。现在你不用导入多个不同的模块例如glob , os , 和 shutilpathlib 就够了:

from pathlib import Path

for file_path in Path.cwd().glob("*.txt"):
    new_path = Path("archive") / file_path.name
    file_path.replace(new_path)

和第一个例子一样,这段代码找到当前文件夹下的文本文件,然后移动到一个 archive/ 子文件夹下。然而,有了 pathlib 你用很少的 import 语句和直观的语法就能完成同样的目的,在接下来的章节里你会学到更多。

用Python的pathlib把路径实例化

pathlib 的初衷之一就是用专门的对象来表示文件系统, instead of strings (而不是字符串)。确切地说,official documentation of pathlibpathlib的官方文档)称之为面向对象的文件系统路径(Object-oriented filesystem paths)

当你把 pathlib 的语法和老的 os.path 的方式相比较时, object-oriented approach (面向对象的方式)是很明显的。当你注意到pathlib 的核心是 Path 类时,这就更明显了:

如果你从来没用过这个模块或者不知道用哪个类,基本用 Path 就对了。 (Source)

事实上,Path 太常用了以至于你一般可以直接把它导入进来:

>>> from pathlib import Path
>>> Path
<class 'pathlib.Path'>

由于你基本上都在跟 pathlib 中的 Path 类打交道,这种导入 Path 的方式能让你在码代码时省些功夫。这样的话,你可以直接使用 Path ,而不是将 pathlib 整个模块导入,然后用 pathlib.Path

还有些别的方式实例化一个 Path 对象。在这个章节里,你会学习如何通过 class methods (类方法)、传入字符串或是拼接路径来创建路径。

使用Path类的方法

你导入 Path 之后,就能用现有的方法来获取当前工作路径或是home路径

当前工作路径是文件系统里当前进程所处的路径。你编程时,比如说,想要创建或打开一个跟你正在执行的脚本同路径的文件,就需要确定当前工作路径。

此外,跟文件打交道时知道用户home路径也很有用。将home路径作为起点,你就可以在不同的机器(操作系统)里指定任意路径,不论用户名是什么。

为了获取当前工作路径,你可以使用 .cwd()

>>> from pathlib import Path
>>> Path.cwd()
WindowsPath('C:/Users/philipp/Desktop/realpython') # Windows
PosixPath('/home/philipp/Desktop/realpython') # Linux
PosixPath('/Users/philipp/Desktop/realpython') # macOS

当你实例化 pathlib.Path ,你得到一个 WindowsPath 或是 PosixPath 对象,取决于你正在使用的操作系统。

在Windows里,.cwd() 返回一个 WindowsPath 。在Linux和macOS里,你得到一个 PosixPath 。尽管内部细节不同,这些对象给你提供了完全一致的接口。

操作系统差异

可能你会显式地要求一个 WindowsPathPosixPath ,但这样除了让你的代码受限于操作系统类型之外没有任何好处。一个下面这样的具体路径在别的操作系统就不起作用了:

>>> import pathlib
>>> pathlib.WindowsPath("test.md")
Traceback (most recent call last):
...
NotImplementedError: cannot instantiate 'WindowsPath' on your system

当如果你就想在Windows机器上操作Unix路径,或是反过来呢?这样的话,你可以在任何系统上直接实例化 PureWindowsPath 或是 PurePosixPath 。当你这样来创建路径,在内部就创建了一个 PurePath object 。如果你需要表示一个路径而不去访问底层文件系统,就可以使用这样的对象。

一般地,使用 Path 是不错的。有了 Path ,你就可以实例化一个当前操作系统的具体的路径,而你的代码又不会受操作系统限制。具体的路径允许你对Path对象进行系统级的调用,但是**纯路径(pure path)**只允许你操作路径,而不能访问。

使用不依赖操作系统的路径意味着你在Windows操作系统上写进脚本里的 Path.cwd() 在macOS或Linux上也能运行。当然,这一点对 .home() 也适用:

>>> from pathlib import Path
>>> Path.home()
WindowsPath('C:/Users/philipp') # Windows
PosixPath('/home/philipp') # Linux
PosixPath('/Users/philipp') # macOS

有了 Path.cwd()Path.home() ,你在Python脚本里就可以很方便地获取到一个出发点。如果你需要把路径拼出来,或是引用子目录结构,就可以通过字符串实例化 Path

传入一个字符串

除了以home路径或工作路径为出发点,你还可以传入字符串来指向它代表的路径:

>>> from pathlib import Path
>>> Path(r"C:\Users\philipp\realpython\file.txt")
WindowsPath('C:/Users/philipp/Desktop/realpython/file.txt') # Windows
PosixPath('/home/philipp/Desktop/realpython/file.txt') # Linux
PosixPath('/Users/philipp/Desktop/realpython/file.txt') # macOS

这些步骤创建了一个 Path 对象。你不用处理字符串,相反,可以用 pathlib 提供的更灵活的方案。

在Windows上,路径分隔符是反斜杠(\)。然而,在许多情况下,反斜杠也被用作 escape character (转义字符),用来代表不可打印的字符。为了避免出问题,使用原始字符串字面量来表示Windows路径:

>>> r"C:\Users"
'C:\\Users'

r 开头的字符串是原始字符串字面量。在原始字符串字面量里, \ 代表了一个字面量反斜杠。在普通字符串里,你需要使用两个反斜杠(\ \)来表明你希望使用字面量反斜杠而不是转义字符。

**注意:**一种获取当前模块工作路径的地道方式是使用 __file__

# hello.py

from pathlib import Path

print(f"You can find me here: {Path(__file__).parent}!")

__file__ attribute__file__属性)包含了Python当前导入或是运行的文件路径。如果需要操作模块本身的路径,你可以把 __file__ 传给 Path 。比如,也许你想用 .parent 获取父级路径。

你也许已经注意到了,即使在Windows里你输入路径时用的反斜杠, pathlib 也会在表示路径时用斜杠(/)作为路径分隔符。这种表示方式称作POSIX风格

POSIX是 Portable Operating System Interface 的缩写,是一种兼容不同操作系统的标准。这个标准的内容远不止路径的表示法。你在 Open Group Base Specifications Issue 7 里能了解到更多。

同样地,当你把一个Path对象转回字符串,它也会回到本地形式——例如,Windows里就是反斜杠:

>>> from pathlib import Path
>>> str(Path(r"C:\Users\gahjelle\realpython\file.txt"))
'C:\\Users\\gahjelle\\realpython\\file.txt'

通常来说,为了方便,你的代码里应该尽可能使用 Path 对象,但是在特定情况下转回字符串也是必要的。一些库和API仍然希望你传入字符串形式的文件路径,此时你就需要在传入特定的函数前,先把 Path 对象转成字符串。

拼接路径

第三种构造Path对象的方法是用斜杠来连接路径的各个部分,这可能是 pathlib 库里最不常用的功能。你可能在本教程刚开始的例子中就已经吃惊过一次了:

from pathlib import Path

for file_path in Path.cwd().glob("*.txt"):
    new_path = Path("archive") / file_path.name
    file_path.rename(new_path)

正斜杠运算符可以连接多个路径或是连接路径和字符串,只要这中间有一个Path对象就行。不管你的操作系统实际用什么作为路径分隔符,这里都用正斜杠。

如果你不喜欢这种特殊的正斜杠符号,也可以用 .joinpath() 方法来做到同样的事:

>>> from pathlib import Path
>>> Path.home().joinpath("python", "scripts", "test.py")
PosixPath('/home/gahjelle/python/scripts/test.py')

这种方式更接近你以前可能用过的 os.path.join() 。尤其是如果你已经习惯了反斜杠来分隔路径,那么.joinpath()是一种对你来说更熟悉的方式,而不是正斜杠。

在你实例化 Path 之后,你可能想对它做点什么。比如,也许你想执行文件操作,或是从路径里截取一些部分。这就是你接下来要做的。

用Path进行文件系统操作

通过使用 pathlib ,你可以方便地 operations on your file system (对文件系统)做一大堆操作。在这个章节,你将对一些最常用的功能有一个宽泛概念。但是在你开始操作文件之前,看看一个路径有哪些部分。

获取路径的各个部分

一个文件或文件夹路径由不同部分组成。当你使用 pathlib ,这些部分以属性的形式方便地供你获取。基本有这些:

  • .name:不含文件夹的纯文件名
  • .stem:不含后缀的文件名
  • .suffix:文件后缀名
  • .anchor:各级文件夹之前的部分
  • .parent:包含了该路径的父级文件夹

这里,你可以上手观察这些属性:

Windows:

>>> from pathlib import Path
>>> path = Path(r"C:\Users\gahjelle\realpython\test.md")
>>> path
WindowsPath('C:/Users/gahjelle/realpython/test.md')

>>> path.name
'test.md'

>>> path.stem
'test'

>>> path.suffix
'.md'

>>> path.anchor
'C:\\'

>>> path.parent
WindowsPath('C:/Users/gahjelle/realpython")

>>> path.parent.parent
WindowsPath('C:/Users/gahjelle')

Linux:

>>> from pathlib import Path
>>> path = Path("/home/gahjelle/realpython/test.md")
>>> path
PosixPath("/home/gahjelle/realpython/test.md")

>>> path.name
'test.md'

>>> path.stem
'test'

>>> path.suffix
'.md'

>>> path.anchor
'/'

>>> path.parent
PosixPath("/home/gahjelle/realpython")

>>> path.parent.parent
PosixPath('/home/gahjelle')

macOS:

>>> from pathlib import Path
>>> path = Path("/users/gahjelle/realpython/test.md")
>>> path
PosixPath("/users/gahjelle/realpython/test.md")

>>> path.name
'test.md'

>>> path.stem
'test'

>>> path.suffix
'.md'

>>> path.anchor
'/'

>>> path.parent
PosixPath("/users/gahjelle/realpython")

>>> path.parent.parent
PosixPath('/users/gahjelle')

注意 .parent 返回的是新的 Path 对象,而其他属性返回的是字符串。这就是说,例如,你可以像最后一个例子那样连着用 .parent ,甚至再跟正斜杠组合使用来创造全新的路径:

>>> path.parent.parent / f"new{path.suffix}"
PosixPath('/home/gahjelle/new.md')

要记的属性相当多。如果你想在引用这些 Path 属性方便一点,可以点这个链接下载Real Python的pathlib小抄:

Free Download: Click here to claim your pathlib cheat sheet so you can tame the file system with Python.

读写文件

试想一下,你想 print 出一个 Markdown 文档里的购物清单。这个 shoppping_list.md 长这样:

<!-- shopping_list.md -->

# Shopping List

## Fruit

* Banana
* Apple
* Peach

## Candy

* Chocolate
* Nougat Bits

传统做法来说, read or write a file in Python (在Python里读写文件)都是用内置的 open() 函数。有了 pathlib ,你可以直接对Path 对象使用 open()

所以,这个找到并打印shopping_list.md中物件的脚本的第一份草稿长这样:

# read_shopping_list.py

from pathlib import Path

path = Path.cwd() / "shopping_list.md"
with path.open(mode="r", encoding="utf-8") as md_file:
    content = md_file.read()
    groceries = [line for line in content.splitlines() if line.startswith("*")]
print("\n".join(groceries))

事实上, Path.open() 底层就是在调用 built-in open() (内置open())函数。这就是为什么你在 Path.open() 里可以使用 modeencoding 这些参数。

除此之外, pathlib 提供了一些便于读写文件的方法:

  • .read_text() 以文本模式打开路径并返回字符串格式的内容。
  • .read_bytes() 以二进制模式打开路径并返回字节字符串的内容。
  • .write_text() 打开路径并写入字符串数据。
  • .write_bytes() 以二进制模式打开路径并写入数据。

上面每个方法都能打开并关闭文件。因此,你可以用 .read_text() 更新 read_shopping_list.py

# read_shopping_list.py

from pathlib import Path

path = Path.cwd() / "shopping_list.md"
content = path.read_text(encoding="utf-8")
groceries = [line for line in content.splitlines() if line.startswith("*")]
print("\n".join(groceries))

如果你想创建一个只包含了杂货的购物清单,可以以相似的方式使用 .write_text()

# write_plain_shoppinglist.py

from pathlib import Path

content = Path("shopping_list.md").read_text(encoding="utf-8")
groceries = [line for line in content.splitlines() if line.startswith("*")]

Path("plain_list.md").write_text("\n".join(groceries), encoding="utf-8")

当使用 .write_text() 时,Python会在没有提示的情况下覆写同路径的文件。这就是说你一步操作就会让所有辛苦工作付之东流!一如既往地,当你在Python里写入文件时,对代码正在做的事应该很谨慎,重命名时也一样。

重命名文件

当你希望重命名文件,你可以使用 .with_stem().with_suffix() , 或者 .with_name() 。这些方法会返回原始路径,但替换了文件名/文件后缀/或两者:

>>> from pathlib import Path
>>> txt_path = Path("/home/gahjelle/realpython/hello.txt")
>>> txt_path
PosixPath("/home/gahjelle/realpython/hello.txt")

>>> md_path = txt_path.with_suffix(".md")
PosixPath('/home/gahjelle/realpython/hello.md')

>>> txt_path.replace(md_path)

使用 .with_suffix() 返回了一个新的路径,接下来你得使用 .replace() 才能实实在在地重命名文件。这会把 txt_path 移动到 md_path 然后在保存时重命名。

如果你想改变整个文件名,包括后缀,那么你可以用 .with_name()

>>> from pathlib import Path
>>> txt_path = Path("/home/gahjelle/realpython/hello.txt")
>>> txt_path
PosixPath("/home/gahjelle/realpython/hello.txt")

>>> md_path = txt_path.with_name("goodbye.md")
PosixPath('/home/gahjelle/realpython/goodbye.md')

>>> txt_path.replace(md_path)

上面这段代码把 hello.txt 改成了 goodbye.md

如果你只想改变文件名,不想改后缀,就可以用 .with_stem 。你会在下一个章节学习这个方法。

复制文件

令人惊讶的是,Path 没有提供任何复制文件的方法。但是有了前面学到的 pathlib 的知识,你可以用较少的代码创造这个功能:

>>> from pathlib import Path
>>> source = Path("shopping_list.md")
>>> destination = source.with_stem("shopping_list_02")
>>> destination.write_bytes(source.read_bytes())

你使用 .with_stem() 在不改变后缀的情况下创建新的文件名。实际的复制行为发生在最后一行,你使用 .read_bytes() 来读取 source 的内容,然后使用 .write_bytes() 把内容写入 destination

虽然使用 pathlib 来处理所有跟路径相关的事具有诱惑力,但你确实也会想 using shutil for copying files (使用shutil来复制文件)。用 Path 对象来复制文件也是个不错的选择。

移动、删除文件

通过 pathlib ,你也可以进行基础系统级别的文件操作,例如移动、更新,甚至删除文件。大多数情况下,这些方法在删除信息、文件前都没有警告或是等待确认。所以,使用的时候要小心。

要移动一个文件,你可以使用 .replace() 。注意如果目标路径已经存在,那么 .replace() 会覆写它。为了避免可能的覆写,你可以在移动前测试一下目标路径是否存在:

from pathlib import Path

source = Path("hello.py")
destination = Path("goodbye.py")

if not destination.exists():
    source.replace(destination)

然而,这并没有考虑到可能的 race condition (竞态条件)。另一个进程可能刚好在本进程执行到 if 语句和 .replace() 方法之间时,往 destination 路径下添加了一个文件。如果你担心这样,那么更安全的一种方式是打开目标路径时进行exclusive creation (独占创建)然后显式地复制源数据并在之后删除源文件:

from pathlib import Path

source = Path("hello.py")
destination = Path("goodbye.py")

try:
    with destination.open(mode="xb") as file:
        file.write(source.read_bytes())
except FileExistsError:
    print(f"File {destination} exists already.")
else:
    source.unlink()

如果 destination 已经存在,那么上述代码就会捕获 FileExistsError 然后打印一个警告。为了执行移动操作,你得在复制结束后用 unlink() 删除 source 。使用 else 能确保文件在复制失败时不会被删除。

创建空文件

要用 pathlib 创建空文件,你可以使用 .touch() 。这个方法意在更新文件的修改时间,但你也可以利用他的副作用来创建一个新的文件:

>>> from pathlib import Path
>>> filename = Path("hello.txt")
>>> filename.exists()
False

>>> filename.touch()
>>> filename.exists()
True

>>> filename.touch()

在上面的例子中,你实例化了一个 Path 对象然后用 .touch() 创建了文件。你使用了2次 exists() 来检查文件事先并不存在,并且在之后被成功创建。如果你再次使用 .touch ,那就会更新这个文件的修改时间。

如果你不想一不小心修改了文件,那么可以使用 exist_ok 参数并设成 False

>>> filename.touch(exist_ok=False)
Traceback (most recent call last):
  ...
FileExistsError: [Errno 17] File exists: 'hello.txt'

当你对一个不存在的文件路径使用 .touch() ,可以创建一个空文件。如果你想先把文件名存下来待会儿使用,暂时还没什么需要写入的,那么用Path.touch() 创建一个空的文件就有用。例如,你可能想创建一个空文件来确保某个文件名是可用的,即使现在没什么内容要写入。

Python pathlib 案例

在这个章节,你会看到一些使用 pathlib 解决Python开发者日常挑战的案例。你可以在你的代码中,将这些案例作为出发点,或是存下来之后使用。

统计文件个数

有各种方式来 get a list of all the files in a directory with Python (用Python获取目录下的文件列表)。有了 pathlib ,你可以方便地使用 iterdir() 方法,它会迭代给定目录下的所有文件。在下面的例子中,你结合了 iterdir()collections.Counter class 来统计当前目录下的每种文件的个数:

>>> from pathlib import Path
>>> from collections import Counter
>>> Counter(path.suffix for path in Path.cwd().iterdir())
Counter({'.md': 2, '.txt': 4, '.pdf': 2, '.py': 1})

你可以用 .glob().rglob() 方法创建更多灵活的文件列表。例如, Path.cwd().glob(".txt") 返回当前目录下所有含 .txt 后缀的文件。接下来,你只统计后缀以 p 开头的文件:

>>> Counter(path.suffix for path in Path.cwd().glob("*.p*"))
Counter({'.pdf': 2, '.py': 1})

如果你想递归搜索当前目录及其子目录下的所有文件,就用 .rglob() 。这个方法还提供了炫酷的方式来展示文件夹树,看下一个例子。

展示一个文件夹树

在这个例子中,你定义了一个 tree() 函数,会打印出代表文件结构的可视化树,以给定的目录作为根节点。这通常,举个例子,在你想浏览一遍项目子文件夹时很有用。

要遍历子文件夹, 你使用 .rglob() method

# display_dir_tree.py

def tree(directory):
    print(f"+ {directory}")
    for path in sorted(directory.rglob("*")):
        depth = len(path.relative_to(directory).parts)
        spacer = "    " * depth
        print(f"{spacer}+ {path.name}")

注意,你需要知道一个文件的位置离根节点有多远。要做到这点,你先是用了 .relative_to() 来表示与根目录的相对路径。然后,你又用了 .parts 属性来统计路径表示中的文件夹层级数。当函数运行时,就会创建一个下面这样的可视化树:

>>> from pathlib import Path
>>> from display_dir_tree import tree
>>> tree(Path.cwd())
+ /home/gahjelle/realpython
    + directory_1
        + file_a.md
    + directory_2
        + file_a.md
        + file_b.pdf
        + file_c.py
    + file_1.txt
    + file_2.txt

如果你还想提升这段代码,那么你可以尝试创建 directory tree generator for the command line (命令行中的目录树生成器)。

找到最近修改的文件

.iterdir().glob().rglob() 方法都很适合 generator expressions (生成器语法)和 list comprehensions (列表推导式)。要找到最近修改的文件,你可以使用 .stat() 方法来获取底层文件的信息。例如, .stat.st_mtime 提供了文件的最近修改时间:

>>> from pathlib import Path
>>> from datetime import datetime
>>> directory = Path.cwd()
>>> time, file_path = max((f.stat().st_mtime, f) for f in directory.iterdir())
>>> print(datetime.fromtimestamp(time), file_path)
2023-03-28 19:23:56.977817 /home/gahjelle/realpython/test001.txt

.stat().st_mtime 这样的属性返回的时间戳代表从1970年1月1日至今的秒数,也称作 epoch 。如果你喜欢别的格式,可以用 time.localtime 或是 time.ctime 来把时间戳转换成更合适的格式。如果上面的例子点燃了你的好奇心,那么你也许想继续了解 how to get and use the current time in Python (在Python里如何获取并使用当前时间)。

创建独一无二的文件名

在最后这个例子里,你会构造独一无二的基于一定字符串模板的数字编号文件名。如果你不想覆写已有文件,这就显得很有用:

# unique_path.py

def unique_path(directory, name_pattern):
    counter = 0
    while True:
        counter += 1
        path = directory / name_pattern.format(counter)
        if not path.exists():
            return path

unique_path() 里,你为文件名指定了一个模板,内部留有计数变量的位置。然后,你检查了组合目录和文件名之后的新路径是否存在,文件名里有计数变量的值。如果已经存在了,就增加计数变量,再次尝试。

现在你可以运行上面的代码来获取独一无二的文件名了:

>>> from pathlib import Path
>>> from unique_path import unique_path
>>> template = "test{:03d}.txt"
>>> unique_path(Path.cwd(), template)
PosixPath("/home/gahjelle/realpython/test003.txt")

如果目录下已经有 test001.txttest002.txt ,那上面的代码就会把 path 设成 test003.txt

结语

Python的 pathlib 模块提供了现代化、Pythonic的方式来处理文件路径,让代码可读性更强、更容易维护。有了 pathlib ,你可以用专门的 Path 对象来表示文件路径,而不是纯字符串。

在本教程中,你学到了:

  • 在Python里处理文件和文件夹的路径
  • 以多种方式实例化一个 Path 对象
  • 使用 pathlib读写文件
  • 谨慎地复制、移动和删除文件
  • 操作路径和底层文件系统
  • 获取路径的各个部分

pathlib 模块通过提供有用的方法和属性,让处理文件路径更加方便。不同系统的特异性也被 Path 对象隐藏了起来,使得你的代码在不同操作系统中能保持一致。

如果你想获取一个总结性的PDF,包含了 pathlib 提供的方便的方法和属性,可以点击下方链接:

Free Download: Click here to claim your pathlib cheat sheet so you can tame the file system with Python.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值