我过去常常打开与当前运行的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应用程序绑定资源,它的工作就像一个魅力!
我总是用:
__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应用程序绑定资源,它的工作就像一个魅力!
我是这么做的
sys。Argv始终是你输入到终端或使用python.exe或pythonw.exe执行时使用的文件路径
例如,你可以用几种方式运行文件text.py,它们都会给你不同的答案它们总会给你python输入的路径。
C:\Documents and Settings\Admin>python test.py
sys.argv[0]: test.py
C:\Documents and Settings\Admin>python "C:\Documents and Settings\Admin\test.py"
sys.argv[0]: C:\Documents and Settings\Admin\test.py
你可以知道文件名,这很重要,现在要知道应用目录你可以使用os。路径,特别是abspath和dirname
import sys, os
print os.path.dirname(os.path.abspath(sys.argv[0]))
这将输出:
C:\Documents and Settings\Admin\
不管你输入的是python test.py还是python "C:\Documents and Settings\Admin\test.py"
使用__file__的问题
考虑以下两个文件
test.py
import sys
import os
def paths():
print "__file__: %s" % __file__
print "sys.argv: %s" % sys.argv[0]
a_f = os.path.abspath(__file__)
a_s = os.path.abspath(sys.argv[0])
print "abs __file__: %s" % a_f
print "abs sys.argv: %s" % a_s
if __name__ == "__main__":
paths()
import_test.py
import test
import sys
test.paths()
print "--------"
print __file__
print sys.argv[0]
"python test.py"输出
C:\Documents and Settings\Admin>python test.py
__file__: test.py
sys.argv: test.py
abs __file__: C:\Documents and Settings\Admin\test.py
abs sys.argv: C:\Documents and Settings\Admin\test.py
python test_import.py的输出
C:\Documents and Settings\Admin>python test_import.py
__file__: C:\Documents and Settings\Admin\test.pyc
sys.argv: test_import.py
abs __file__: C:\Documents and Settings\Admin\test.pyc
abs sys.argv: C:\Documents and Settings\Admin\test_import.py
--------
test_import.py
test_import.py
如你所见,file总是给你运行它的python文件,而sys。Argv[0]给出了你总是从解释器运行的文件。根据你的需要,你需要选择一个最适合你的需求。