在Python的相对位置打开文件


132

假设python代码在以前的Windows目录“ main”中未知的位置执行,并且在运行时将代码安装在任何地方,都需要访问目录“ main / 2091 / data.txt”。

我应该如何使用open(location)函数?应该在什么位置?

编辑:

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

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

1
您正在使用未转义的反斜杠。那是一个缺点。
orip 2011年

6
几个缺点。1)按照@orip,即使在Windows上,也使用正斜杠表示路径。您的字符串不起作用。或使用类似的原始字符串r"\2091\sample.txt"。或者像那样逃避他们"\\2091\\sample.txt"(但这很烦人)。同样,2)您正在使用getcwd(),这是执行脚本时所在的路径。我以为您想要相对于脚本位置(但现在很奇怪)。3),始终使用os.path函数来操纵路径。您的路径加入行应为os.path.join(os.getcwd(), file)4);是没有意义的
Russ

3
并且采取了很好的措施... 5)使用上下文防护来保持其干净,并避免忘记关闭文件:with open(path, 'r+') as fp:。请参阅此处,以获得对with我所见陈述的最佳解释。
罗斯,

如前所述,除了必要的斜杠保护外,还具有os.path.abspath轻松获取相对路径打开的完整路径的功能。最终声明如下:os.path.abspath('./2091/sample.txt')
OPMendeavor

Answers:


189

使用这种类型的东西时,您需要注意实际的工作目录是什么。例如,您可能无法从文件所在的目录中运行脚本。在这种情况下,您不能仅使用相对路径本身。

如果确定所需文件位于脚本实际所在的子目录中,则可以__file__在此处使用帮助。 __file__是您正在运行的脚本所在的完整路径。

因此,您可以摆弄这样的东西:

import os
script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

我发现下面的简单代码可以工作..它有什么缺点吗?<pre> file =“ \ sample.txt” path = os.getcwd()+ str(loc)+ file fp = open(path,'r +'); <code>

@Arash的缺点是cwd(当前工作目录)可以是任何东西,不一定是脚本所在的位置。
Cory Mawhorter 2013年

5
__file__是相对路径(由于某种原因,至少在我的设置中是这样),您需要先调用os.path.abspath(__file__)。osx / homebrew 2.7
Cory Mawhorter

2
os.path.dirname(file)在Python 2.7中对我不起作用。它显示NameError: name '__file__' is not defined
Soumendra

1
@Soumendra我想您正在控制台中尝试。在* .py文件中尝试。
Enku

35

这段代码可以正常工作:

import os


def readFile(filename):
    filehandle = open(filename)
    print filehandle.read()
    filehandle.close()



fileDir = os.path.dirname(os.path.realpath('__file__'))
print fileDir

#For accessing the file in the same folder
filename = "same.txt"
readFile(filename)

#For accessing the file in a folder contained in the current folder
filename = os.path.join(fileDir, 'Folder1.1/same.txt')
readFile(filename)

#For accessing the file in the parent folder of the current folder
filename = os.path.join(fileDir, '../same.txt')
readFile(filename)

#For accessing the file inside a sibling folder.
filename = os.path.join(fileDir, '../Folder2/same.txt')
filename = os.path.abspath(os.path.realpath(filename))
print filename
readFile(filename)

对我来说,访问当前文件夹的父文件夹中的文件并没有worked..the ..添加为字符串..
M.保罗

在Windows上不起作用。文件路径正确,但是Python指出“找不到文件”,并使用\\分隔符显示路径。
lonstar

26

我创建一个帐户只是为了澄清我认为在Russ原始回复中发现的差异。

作为参考,他的原始答案是:

import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

这是一个很好的答案,因为它试图动态创建所需文件的绝对系统路径。

Cory Mawhorter注意到这__file__是相对路径(在我的系统上也是这样),建议使用os.path.abspath(__file__)os.path.abspath,但是,返回当前脚本的绝对路径(即/path/to/dir/foobar.py

要使用此方法(以及我最终如何使用它),必须从路径末尾删除脚本名称:

import os
script_path = os.path.abspath(__file__) # i.e. /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] #i.e. /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

所得的abs_file_path(在此示例中)变为: /path/to/dir/2091/data.txt


14
您甚至可以将两种方法组合在一起,以简化操作os.path.dirname(os.path.abspath(__file__))
Luke Taylor

1
@LukeTaylor确实,这比os.path.dirname像我去年在回答中所做的那样自己尝试复制功能要好。
Grant Hulegaard

19

这取决于您使用的操作系统。如果您想要一个与Windows和* nix兼容的解决方案,例如:

from os import path

file_path = path.relpath("2091/data.txt")
with open(file_path) as f:
    <do stuff>

应该工作正常。

path模块能够格式化其正在运行的任何操作系统的路径。另外,只要您具有正确的权限,python就能很好地处理相对路径。

编辑

正如kindall在评论中提到的那样,python仍然可以在unix样式和Windows样式路径之间进行转换,因此,即使是更简单的代码也可以使用:

with open("2091/data/txt") as f:
    <do stuff>

话虽如此,该path模块仍然具有一些有用的功能。


3
relpath()将路径名转换为相对路径。由于它已经是一条相对路径,因此将无济于事。
kindall 2011年

如果合适的话,它将把它从unix风格的路径转换成Windows风格的路径。os.path模块中是否还有另一个更好的选择?
Wilduck

1
Windows已经可以使用UNIX样式的路径正常工作。至少基于NT的系列(2000,XP,Vista,7)。无需转换。
kindall 2011年

7
这个答案不太正确,会引起问题。默认情况下,相对路径是相对于当前工作目录(执行脚本的路径),而不是实际脚本位置。您需要使用__file__。请看我的回答。
罗斯,

这个答案的作者是否将os.path.relpath与os.path.abspath混淆了?
foob​​arbecue '16

15

我花了很多时间发现为什么我的代码找不到在Windows系统上运行Python 3的文件。所以我加了。之前/一切正常:

import os

script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')

更好:file_path = os.path.join(script_dir, 'output03.txt')
Mr_and_Mrs_D

我在Windows操作系统上尝试过,但是没有成功。
恩戈洛·波洛托

有趣-您可以打印script_dir吗?然后将其转到绝对路径中,例如script_dir = os.path.abspath(os.path.dirname(__file__))
Mr_and_Mrs_D

我会尝试的,如果成功,我将更改答案。
恩戈洛·波洛托

6

码:

import os
script_path = os.path.abspath(__file__) 
path_list = script_path.split(os.sep)
script_directory = path_list[0:len(path_list)-1]
rel_path = "main/2091/data.txt"
path = "/".join(script_directory) + "/" + rel_path

说明:

导入库:

import os

用于__file__获取当前脚本的路径:

script_path = os.path.abspath(__file__)

将脚本路径分为多个项目:

path_list = script_path.split(os.sep)

删除列表中的最后一项(实际的脚本文件):

script_directory = path_list[0:len(path_list)-1]

添加相对文件的路径:

rel_path = "main/2091/data.txt

加入列表项,并添加相对路径的文件:

path = "/".join(script_directory) + "/" + rel_path

现在,您可以设置要对文件执行的任何操作,例如:

file = open(path)

而不是path = "/".join(script_directory) + "/" + rel_path您应该像中那样使用os模块path = os.path.join(script_directory, rel_path)。代替手动解析路径,您应该使用script_path = os.path.dirname(__file__)
Mr_and_Mrs_D

3

如果文件在您的父文件夹中,例如。follower.txt,您可以简单地使用open('../follower.txt', 'r').read()


3

试试这个:

from pathlib import Path

data_folder = Path("/relative/path")
file_to_open = data_folder / "file.pdf"

f = open(file_to_open)

print(f.read())

Python 3.4引入了一个新的用于处理文件和路径的标准库,称为pathlib。这个对我有用!


2

不确定是否到处都能使用。

我在ubuntu中使用ipython。

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

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

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

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

1

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

您可能会发现,回答此类问题的最简单方法是尝试一下,看看会发生什么。


2
不正确...脚本中的工作目录是您从中运行脚本的位置,而不是脚本的位置。如果您从其他地方运行脚本(也许脚本在系统路径中),则子目录的相对路径将不起作用。请参阅我关于如何解决此问题的答案。
罗斯,

@Russ-OP的示例使用getcwd()。我将原始描述读为“相对于运行脚本的位置,无论代码位于何处”。
orip 2011年

@orip-OP在问题后3小时添加了getcwd()调用。没关系...继续前进。:)
罗斯,

1
import os
def file_path(relative_path):
    dir = os.path.dirname(os.path.abspath(__file__))
    split_path = relative_path.split("/")
    new_path = os.path.join(dir, *split_path)
    return new_path

with open(file_path("2091/data.txt"), "w") as f:
    f.write("Powerful you have become.")

0

当我还是初学者时,我发现这些描述有些令人生畏。一开始我会尝试 For Windows

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

这将引发一个syntax error。我曾经很困惑。然后在Google上进行一些冲浪之后。找到了发生错误的原因。写给初学者

这是因为要以Unicode读取路径,您只需\在启动文件路径时添加一个

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

现在,它可以\在启动目录之前添加。


1
反斜杠是几个字符的转义字符。如果碰巧遇到\t类似的情况\top\directory,则'\ t'会被解释为制表符,而您的“ trick”则会失败。最好的选择是使用原始字符串格式r'C:\Users\chidu\Desktop\Skipper New\Special_Note.txt',而不尝试“转义”字符。
罗纳德
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.