我过去常常打开与当前运行的Python脚本在同一目录下的文件,只需使用如下命令:

open("Some file.txt", "r")

然而,我发现当在Windows中双击该脚本时,它会试图从错误的目录打开文件。

从那以后,我一直使用表单的命令

open(os.path.join(sys.path[0], "Some file.txt"), "r")

每当我想打开一个文件。这适用于我的特定用法,但我不确定sys。路径[0]可能在其他用例中失败。

所以我的问题是:打开与当前运行的Python脚本位于同一目录下的文件的最佳和最可靠的方法是什么?

以下是我目前所了解到的情况:

os.getcwd() and os.path.abspath('') return the "current working directory", not the script directory. os.path.dirname(sys.argv[0]) and os.path.dirname(__file__) return the path used to call the script, which may be relative or even blank (if the script is in the cwd). Also, __file__ does not exist when the script is run in IDLE or PythonWin. sys.path[0] and os.path.abspath(os.path.dirname(sys.argv[0])) seem to return the script directory. I'm not sure if there's any difference between these two.

编辑:

我刚刚意识到,我想做的事情应该更好地描述为“在包含模块的同一目录中打开一个文件”。换句话说,如果我导入了一个我在另一个目录下编写的模块,而该模块打开了一个文件,我希望它在模块的目录下查找该文件。我不认为我发现的任何东西都能做到这一点……


当前回答

我总是用:

__location__ = os.path.realpath(
    os.path.join(os.getcwd(), os.path.dirname(__file__)))

join()调用将当前工作目录放在前面,但是文档说,如果某个路径是绝对路径,则丢弃它剩下的所有其他路径。因此,当dirname(__file__)返回一个绝对路径时,getcwd()将被删除。

此外,如果找到符号链接,realpath调用将解析符号链接。这避免了在Linux系统上使用setuptools部署时的麻烦(脚本被符号链接到/usr/bin/—至少在Debian上)。

您可以使用以下方法打开同一文件夹中的文件:

f = open(os.path.join(__location__, 'bundled-resource.jpg'))
# ...

我用它在Windows和Linux上与几个Django应用程序绑定资源,它的工作就像一个魅力!

其他回答

你能试试这个简单的方法吗?

    import os

    my_local_file = os.path.join(os.path.dirname(__file__), 'some_file.txt')

    f = open(my_local_file,  "r")
    my_local_data = f.read()

在Python 3.4中,添加了pathlib模块,下面的代码将可靠地打开与当前脚本相同目录下的文件:

from pathlib import Path

p = Path(__file__).with_name('file.txt')
with p.open('r') as f:
    print(f.read())

如果你需要文件路径作为一个字符串来使用一些类似开放的API,你可以使用absolute():

p = Path(__file__).with_name('file.txt')
filename = p.absolute()

注意:Python reps,如运行Python命令而不带目标或ipython,不会公开__file__。

我通常使用以下方法。它适用于测试,也可能适用于其他用例。

使用open(os.path.join(os.path.dirname(__file__), 'some_file.txt'), 'r')作为f:

建议登录https://stackoverflow.com/questions/10174211/how-to-make-an-always-relative-to-current-module-file-path


我总是用:

__location__ = os.path.realpath(
    os.path.join(os.getcwd(), os.path.dirname(__file__)))

join()调用将当前工作目录放在前面,但是文档说,如果某个路径是绝对路径,则丢弃它剩下的所有其他路径。因此,当dirname(__file__)返回一个绝对路径时,getcwd()将被删除。

此外,如果找到符号链接,realpath调用将解析符号链接。这避免了在Linux系统上使用setuptools部署时的麻烦(脚本被符号链接到/usr/bin/—至少在Debian上)。

您可以使用以下方法打开同一文件夹中的文件:

f = open(os.path.join(__location__, 'bundled-resource.jpg'))
# ...

我用它在Windows和Linux上与几个Django应用程序绑定资源,它的工作就像一个魅力!

在尝试了所有这些解决方案之后,我仍然遇到了不同的问题。因此,我发现最简单的方法是创建一个python文件:config.py,其中包含文件的绝对路径,并将其导入脚本。 类似的

import config as cfg 
import pandas as pd 
pd.read_csv(cfg.paths['myfilepath'])

config.py里面有:

paths = {'myfilepath': 'home/docs/...'}

这不是自动的,但当你必须在不同的目录或不同的机器上工作时,这是一个很好的解决方案。