Python 3:在Windows,Mac和Linux上处理文件路径的简便方法

编程的一个小麻烦是Microsoft Windows在文件夹名称之间使用反斜杠字符,而几乎所有其他计算机都使用正斜杠:

Windows filenames:
C:\some_folder\some_file.txt

Most other operating systems:
/some_folder/some_file.txt

这是1980年代早期的计算机历史事故。MS-DOS的第一个版本使用正斜杠字符指定命令行选项。当Microsoft在MS-DOS 2.0中添加对文件夹的支持时,正斜杠字符已被占用,因此他们使用反斜杠代替。三十五年后,我们仍然坚持这种不相容性。

如果您希望Python代码可以在Windows和Mac / Linux上运行,则需要处理这些特定于平台的问题。幸运的是,Python 3有一个名为pathlib的新模块,可以轻松处理文件。

让我们快速浏览处理文件名路径的不同方法,看看pathlib如何让您的生活更美好!

错误的解决方案:手工构建文件路径

假设您有一个数据文件夹,其中包含您要在Python程序中打开的文件:

这是用Python编写代码的错误方法

data_folder = "source_data/text_files/"

file_to_open = data_folder + "raw_data.txt"

f = open(file_to_open)

print(f.read())

请注意,由于我在Mac上,因此我使用Unix式正斜杠硬编码路径。这将使Windows用户生气。

从技术上讲,这段代码仍然可以在Windows上运行,因为Python有一个hack,当你在Windows上调用open()时它会识别出任何一种斜杠。但即便如此,你也不应该依赖它。如果在错误的操作系统上使用错误的斜杠,并非所有Python库都能正常工作 - 特别是如果它们与外部程序或库接口。

Python对混合斜杠类型的支持是一种仅限Windows,它不能反向运行。在代码中使用反斜杠在Mac上完全失败:

data_folder = "source_data\\text_files\\"

file_to_open = data_folder + "raw_data.txt"

f = open(file_to_open)

print(f.read())

# On a Mac, this code will throw an exception:
# FileNotFoundError: [Errno 2] No such file or directory: 'source_data\\text_files\\raw_data.txt'

出于所有这些原因以及更多原因,使用硬编码路径字符串编写代码会让其他程序员怀疑地看着你。一般来说,你应该尽量避免它。

旧解决方案:Python的os.path模块

Python的os.path模块有许多工具可用于解决这些特定于操作系统的文件系统问题。

使用适合当前操作系统的斜杠构建路径字符串:

import os.path

data_folder = os.path.join("source_data", "text_files")

file_to_open = os.path.join(data_folder, "raw_data.txt")

f = open(file_to_open)

print(f.read())

此代码可在Windows或Mac上完美运行。问题是使用起来很痛苦。写出os.path.join()并将路径的每个部分作为单独的字符串传递是冗长且不直观的。

由于os.path模块中的大多数函数同样令人讨厌,因此开发人员通常会“忘记”使用它们,即使它们知道更好。这导致了许多跨平台的错误和愤怒的用户。

更好的解决方案:Python 3的路径库!

Python 3.4引入了一个新的标准库来处理名为pathlib的文件和路径- 它非常棒

要使用它,只需使用正斜杠将路径或文件名传递给新的Path()对象,然后处理其余的:

from pathlib import Path

data_folder = Path("source_data/text_files/")

file_to_open = data_folder / "raw_data.txt"

f = open(file_to_open)

print(f.read())

请注意两件事:

  1. 您应该使用带有pathlib函数的正斜杠。该路径()对象将向前斜杠转换成正确的那种斜线的当前操作系统。太好了!
  2. 如果要添加到路径,可以直接在代码中使用/运算符。告别一遍又一遍地输入os.path.join(a,b)

如果这就是所有pathlib所做的那样,那将是Python的一个很好的补充 - 但它确实做得更多!

例如,我们可以读取文本文件的内容,而无需打开和关闭文件:

from pathlib import Path

data_folder = Path("source_data/text_files/")

file_to_open = data_folder / "raw_data.txt"

print(file_to_open.read_text())

提示:前面的例子都是错误的,因为打开的文件从未关闭过。这种语法完全避免了这个bug。

实际上,pathlib使大多数标准文件操作变得简单快捷:

from pathlib import Path

filename = Path("source_data/text_files/raw_data.txt")

print(filename.name)
# prints "raw_data.txt"

print(filename.suffix)
# prints "txt"

print(filename.stem)
# prints "raw_data"

if not filename.exists():
    print("Oops, file doesn't exist!")
else:
    print("Yay, the file exists!")

您甚至可以使用pathlib将Unix路径显式转换为Windows格式的路径:

from pathlib import Path, PureWindowsPath

filename = Path("source_data/text_files/raw_data.txt")

# Convert path to Windows format
path_on_windows = PureWindowsPath(filename)

print(path_on_windows)
# prints "source_data\text_files\raw_data.txt"

如果您真的想安全地在代码中使用反斜杠,可以将路径声明为Windows格式,并且pathlib可以将其转换为在当前操作系统上工作:

from pathlib import Path, PureWindowsPath

# I've explicitly declared my path as being in Windows format, so I can use forward slashes in it.
filename = PureWindowsPath("source_data\\text_files\\raw_data.txt")

# Convert path to the right format for the current operating system
correct_path = Path(filename)

print(correct_path)
# prints "source_data/text_files/raw_data.txt" on Mac and Linux
# prints "source_data\text_files\raw_data.txt" on Windows

如果你想更高级一些,你甚至可以使用pathlib来解决相关文件路径,解析网络共享路径和生成file://urls。这是一个示例,它将在您的Web浏览器中打开一个本地文件,只需两行代码:

from pathlib import Path
import webbrowser

filename = Path("source_data/text_files/raw_data.txt")

webbrowser.open(filename.absolute().as_uri())

这只是pathlib的一个小峰值。它是许多不同文件相关功能的绝佳替代品,这些功能过去分散在不同的Python模块中。看看吧


翻译自:https://medium.com/@ageitgey/python-3-quick-tip-the-easy-way-to-deal-with-file-paths-on-windows-mac-and-linux-11a072b58d5f

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容