在Python中的相对位置打开文件[重复]

问题描述 投票:0回答:14

假设我的Python代码在一个名为

main
的目录中执行,并且应用程序需要访问
main/2091/data.txt

我应该如何使用

open(location)
?参数
location
应该是什么?

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

file = "\2091\sample.txt"
path = os.getcwd()+file
fp = open(path, 'r+');
python file path relative-path
14个回答
274
投票

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

如果您确定所需的文件位于脚本实际所在的子目录中,则可以使用

__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)

52
投票

这段代码运行良好:

import os

def read_file(file_name):
    file_handle = open(file_name)
    print file_handle.read()
    file_handle.close()

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

#For accessing the file in the same folder
file_name = "same.txt"
read_file(file_name)

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

#For accessing the file in the parent folder of the current folder
file_name = os.path.join(file_dir, '../same.txt')
read_file(file_name)

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

33
投票

我创建了一个帐户,只是为了澄清我认为在 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


28
投票

这取决于您使用的操作系统。如果您想要一个与 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
模块仍然有一些有用的功能。


22
投票

我花了很多时间来发现为什么我的代码找不到在 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')

14
投票

试试这个:

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。这对我有用!


7
投票

代码:

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)

4
投票
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.")

3
投票

如果文件位于您的父文件夹中,例如。 follower.txt,您可以简单地使用

open('../follower.txt', 'r').read()


3
投票

获取父文件夹的路径,然后

os.join
你的相关文件到最后。

# get parent folder with `os.path`
import os.path

BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# now use BASE_DIR to get a file relative to the current script
os.path.join(BASE_DIR, "config.yaml")

pathlib
相同:

# get parent folder with `pathlib`'s Path
from pathlib import Path

BASE_DIR = Path(__file__).absolute().parent

# now use BASE_DIR to get a file relative to the current script
BASE_DIR / "config.yaml"

2
投票

Python 只是将您提供的文件名传递给操作系统,然后操作系统打开它。如果您的操作系统支持像

main/2091/data.txt
这样的相对路径(提示:确实如此),那么就可以正常工作。

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


2
投票

不确定这是否在所有地方都有效。

我在 ubuntu 中使用 ipython。

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

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

您的脚本位于当前文件夹中 只需尝试这个:

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

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或类似情况)


1
投票

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

For 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)

现在只需在启动目录之前添加

\
就可以了。

© www.soinside.com 2019 - 2024. All rights reserved.