我曾经只使用像这样的命令打开与当前运行的Python脚本位于同一目录中的文件
open("Some file.txt", "r")
但是,我发现当脚本在Windows中通过双击运行时,它会尝试从错误的目录中打开该文件 .
从那以后我使用了表格的命令
open(os.path.join(sys.path[0], "Some file.txt"), "r")
每当我想打开一个文件 . 这适用于我的特定用法,但我不确定 sys.path[0]
在某些其他用例中是否会失败 .
所以我的问题是:打开与当前运行的Python脚本位于同一目录中的文件的最佳和最可靠的方法是什么?
这是我到目前为止能够弄清楚的:
-
os.getcwd()
和os.path.abspath('')
返回"current working directory",而不是脚本目录 . -
os.path.dirname(sys.argv[0])
和os.path.dirname(__file__)
返回用于调用脚本的路径,该路径可能是相对的,甚至是空白的(如果脚本在cwd中) . 此外,当脚本在IDLE或PythonWin中运行时,__file__
不存在 . -
sys.path[0]
和os.path.abspath(os.path.dirname(sys.argv[0]))
似乎返回脚本目录 . 我'm not sure if there'这两者之间有什么区别 .
Edit:
我刚刚意识到我想做的事情会更好地描述为“在与包含模块相同的目录中打开一个文件” . 换句话说,如果我导入了一个模块,我在另一个目录中编写了该模块,并且该模块打开了一个文件,我希望它在模块的目录中查找该文件 . 我认为我发现的任何东西都不能做到这一点......
4 回答
我一直用:
join()
调用前置当前工作目录,但是文档说如果某个路径是绝对路径,那么它的所有其他路径都将被删除 . 因此,当dirname(__file__)
返回绝对路径时,getcwd()
将被删除 .此外,
realpath
调用解析符号链接(如果找到) . 这避免了在Linux系统上使用setuptools进行部署时的麻烦(脚本符号链接到/usr/bin/
- 至少在Debian上) .您可以使用以下命令打开同一文件夹中的文件:
我使用它在Windows和Linux上捆绑资源和几个Django应用程序,它就像一个魅力!
引用Python文档:
sys.path [0]正是您要找的 .
好的,这就是我的工作
sys.argv始终是您在终端中键入的内容,或者在使用python.exe或pythonw.exe执行时用作文件路径
例如,您可以通过多种方式运行text.py文件,它们每个都会给您一个不同的答案,它们总是为您提供键入python的路径 .
好的,知道你可以得到文件名,非常重要,现在要获得你可以知道的应用程序目录使用os.path,特别是abspath和dirname
这将输出:
如果输入python test.py或python“C:\ Documents and Settings \ Admin \ test.py”,它将始终输出此值
The problem with using file 考虑这两个文件test.py
import_test.py
输出“python test.py”
输出“python test_import.py”
因此,您可以看到 file 总是为您提供正在运行的python文件,其中sys.argv [0]为您提供始终从解释器运行的文件 . 根据您的需求,您需要选择最适合您需求的产品 .
我这样做:
上面的代码使用abspath构建文件的绝对路径,相当于使用
normpath(join(os.getcwd(), path))
[来自pydocs] . 然后它检查该文件是否实际exists然后使用上下文管理器打开它,这样您就不必记得在文件句柄上调用close . 恕我直言,这样做会从长远来看为你节省很多痛苦 .