我过去常常打开与当前运行的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.

编辑:

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


当前回答

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

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

config.py里面有:

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

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

其他回答

我总是用:

__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应用程序绑定资源,它的工作就像一个魅力!

我会这样做:

from os.path import abspath, exists

f_path = abspath("fooabar.txt")

if exists(f_path):
    with open(f_path) as f:
        print f.read()

上面的代码使用abspath构建文件的绝对路径,等价于使用normpath(join(os.getcwd(), path))[来自pydocs]。然后它检查该文件是否实际存在,然后使用上下文管理器打开它,这样您就不必记得在文件句柄上调用close。恕我直言,从长远来看,这样做会为你省去很多痛苦。

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

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

config.py里面有:

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

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

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

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

因为我在尝试使用__file__或sys。我是这样做的:

from inspect import getfile
from pathlib import Path


script_path = getfile(lambda: None)
print(script_path)
parent_path = Path(script_path).parent
print(parent_path)

with open(parent_path/'Some file.txt', 'r') as obFile:
    print(obFile.read())