在Python中以相对位置打开文件

212

假设我的Python代码在名为main的目录中执行,应用程序需要访问main/2091/data.txt

我应该如何使用 open(location) ? 参数location应该是什么?

我发现下面这个简单的代码可以工作...它有什么缺点吗?

file = "\2091\sample.txt"
path = os.getcwd()+file
fp = open(path, 'r+');

5
你正在使用未转义的反斜杠,这是一个缺点。 - orip
8
几个缺点。1)按照@orip的建议,即使在Windows上也要使用斜杠来表示路径。否则,您的字符串将无法工作。或者像 r"\2091\sample.txt" 这样使用原始字符串。或者转义它们,如 "\\2091\\sample.txt"(但这很烦人)。还有2)您正在使用getcwd(),它是在执行脚本时所在的路径。我以为您想要相对于脚本位置(但现在不确定了)。3)始终使用os.path函数操作路径。您的路径拼接行应该是os.path.join(os.getcwd(), file) 。4)分号是没有意义的。 - Russ
4
为了保险起见...5)使用上下文管理器来使代码更整洁,并避免忘记关闭文件:with open(path, 'r+') as fp:。点击这里查看我看过的最好的with语句解释。 - Russ
1
除了刚才提到的必要斜杠注意事项外,还有一个函数os.path.abspath可以轻松获取相对路径打开的完整路径。最终语句看起来像这样:os.path.abspath('./2091/sample.txt') - OPMendeavor
14个回答

2
在Python 3.4中(PEP 428),引入了pathlib,允许您以面向对象的方式处理文件:
from pathlib import Path

working_directory = Path(os.getcwd())
path = working_directory / "2091" / "sample.txt"
with path.open('r+') as fp:
    # do magic

关键字 with 也可以确保您的资源得到正确关闭,即使发生了错误(如未处理的 Exception、sigint 或类似情况)。

2

不确定这是否适用于所有情况。

我在Ubuntu中使用IPython。

如果您想读取当前文件夹的子目录中的文件:

/current-folder/sub-directory/data.csv

你的脚本在当前文件夹中, 只需尝试以下操作:

import pandas as pd
path = './sub-directory/data.csv'
pd.read_csv(path)

2

Python只是将您提供的文件名传递给操作系统,然后由操作系统打开它。如果您的操作系统支持相对路径,例如main/2091/data.txt(提示:它支持),那么这样做就可以正常工作。

您可能会发现回答这样的问题最简单的方法是尝试并查看结果。


2
不是这样的...脚本内的工作目录是您运行脚本的位置,而不是脚本的位置。如果您从其他地方运行脚本(也许脚本在系统路径中),则子目录的相对路径将无法正常工作。请参阅我的答案以解决此问题。 - Russ
@Russ - OP的例子使用了getcwd()。我从原始描述中理解为"相对于我运行脚本的位置,无论代码位于哪里"。 - orip
@orip - 问题发布后3小时,OP添加了getcwd()调用。无论如何...继续前进吧。 :) - Russ

1
当我刚开始学习时,我觉得这些描述有点吓人。一开始我会尝试Windows版本。
f= open('C:\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f) 

这将会引发一个“语法错误(syntax error)”。我经常感到困惑。然后在谷歌上冲浪一番后,找到了错误产生的原因。 这篇文章是为初学者写的

这是因为要读取Unicode路径,你只需在文件路径开头添加\

f= open('C:\\Users\chidu\Desktop\Skipper New\Special_Note.txt','w+')
print(f)

现在它可以工作了,只需在目录前面添加\


1
反斜杠是多个字符的转义字符。如果您遇到\t(例如\top\directory),则\t将被解释为制表符,您的“技巧”将会失败。最好的选择是使用原始字符串格式r'C:\Users\chidu\Desktop\Skipper New\Special_Note.txt',它不会尝试“转义”字符。 - Ronald

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接