I used to open files that were in the same directory as the currently running Python script by simply using a command like:
open("Some file.txt", "r")
However, I discovered that when the script was run in Windows by double-clicking it, it would try to open the file from the wrong directory.
Since then I've used a command of the form
open(os.path.join(sys.path[0], "Some file.txt"), "r")
whenever I wanted to open a file. This works for my particular usage, but I'm not sure if sys.path[0]
might fail in some other use case.
So my question is: What is the best and most reliable way to open a file that's in the same directory as the currently running Python script?
Here's what I've been able to figure out so far:
os.getcwd()
andos.path.abspath('')
return the "current working directory", not the script directory.os.path.dirname(sys.argv[0])
andos.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]
andos.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.
Edit:
I just realized that what I want to do would be better described as "open a file in the same directory as the containing module". In other words, if I import a module I wrote that's in another directory, and that module opens a file, I want it to look for the file in the module's directory. I don't think anything I've found is able to do that...
9条答案
按热度按时间vyswwuz21#
I always use:
The
join()
call prepends the current working directory, but the documentation says that if some path is absolute, all other paths left of it are dropped. Therefore,getcwd()
is dropped whendirname(__file__)
returns an absolute path.Also, the
realpath
call resolves symbolic links if any are found. This avoids troubles when deploying with setuptools on Linux systems (scripts are symlinked to/usr/bin/
-- at least on Debian).You may the use the following to open up files in the same folder:
I use this to bundle resources with several Django application on both Windows and Linux and it works like a charm!
i1icjdpr2#
在Python 3.4中,添加了
pathlib
module,下面的代码将可靠地打开与当前脚本位于同一目录中的文件:如果您需要将文件路径作为某个类似
open
的API的字符串,则可以使用absolute()
:dojqjjoe3#
引用Python文档:
在程序启动时初始化时,此列表的第一项path[0]是包含用于调用Python解释器的脚本的目录。(例如,如果交互调用解释器或从标准输入读取脚本),path[0]是空字符串,它指示Python首先在当前目录中搜索模块。注意脚本目录被插入在作为PYTHONPATH结果插入的条目之前。
如果从终端运行脚本,则
sys.path[0]
就是您要查找的内容。但是,如果您有:
所以要小心!
oxalkeyp4#
好吧我是这么做的
sys.argv始终是您在终端中键入的内容,或者在使用python.exe或pythonw.exe执行时用作文件路径
例如,你可以用几种方式运行文件text.py,它们会给予不同的答案,它们总是给出python输入的路径。
好了,你可以得到文件名,这很重要,现在要得到应用程序目录,你可以使用os.path,特别是abspath和dirname
将输出以下内容:
无论您键入python test.py还是python“C:\Documents and Settings\Admin\test.py”,它都将始终输出此内容
使用__file__的问题请考虑以下两个文件test.py
import_测试.py
“python www.example.com“的输出test.py
“python test_import.py”的输出
所以你可以看到,file总是给你运行它的python文件,而sys.argv[0]总是给你从解释器运行的文件。根据你的需要,你需要选择最适合你的文件。
velaa5lx5#
我通常使用以下代码,它适用于测试,也可能适用于其他用例。
with open(os.path.join(os.path.dirname(__file__), 'some_file.txt'), 'r') as f:
建议在https://stackoverflow.com/questions/10174211/how-to-make-an-always-relative-to-current-module-file-path 中使用此答案
c90pui9n6#
你能不能试试这个简单的方法,就像这样:
dl5txlt97#
因为我在尝试使用emacs中的
__file__
或sys.argv[0]
时遇到错误,所以我这样做:4jb9z9bj8#
在尝试了所有这些解决方案之后,我仍然遇到了不同的问题。所以我发现最简单的方法是创建一个python文件:config.py,并使用包含文件绝对路径的字典将其导入到脚本中。
其中config.py包含以下内容:
它不是自动的,但当你必须在不同的目录或不同的机器上工作时,它是一个很好的解决方案。
fhity93d9#
我会这么做:
上面的代码使用abspath建立了一个文件的绝对路径,相当于使用
normpath(join(os.getcwd(), path))
[来自pydocs]。然后检查该文件是否存在,然后使用上下文管理器打开它,这样你就不必记住在文件句柄上调用close。恕我直言,这样做从长远来看会保存很多痛苦。