当前位置:  开发笔记 > 编程语言 > 正文

如何在与Python脚本相同的目录中可靠地打开文件

如何解决《如何在与Python脚本相同的目录中可靠地打开文件》经验,为你挑选了3个好方法。

我曾经只是使用像这样的命令打开与当前运行的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('')返回"当前工作目录",而不是脚本目录.

os.path.dirname(sys.argv[0])os.path.dirname(__file__)返回用于调用脚本的路径,该路径可能是相对的,甚至是空白的(如果脚本在cwd中).此外,__file__当脚本在IDLE或PythonWin中运行时不存在.

sys.path[0]并且os.path.abspath(os.path.dirname(sys.argv[0]))似乎返回脚本目录.我不确定这两者之间是否有任何区别.

编辑:

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



1> André Caron..:

我一直用:

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

join()调用会在当前工作目录之前进行,但文档说如果某个路径是绝对路径,则会删除其余的所有路径.因此,getcwd()dirname(__file__)返回绝对路径时被删除.

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

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

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

我使用它在Windows和Linux上捆绑资源和几个Django应用程序,它就像一个魅力!


如果不能使用`__file__`,则使用`sys.argv [0]`而不是`dirname(__ file __)`.其余的应该按预期工作.我喜欢使用`__file__`,因为在库代码中,`sys.argv [0]`可能根本不指向你的代码,特别是如果通过某些第三方脚本导入的话.

2> RED MONKEY..:

引用Python文档:

在程序启动时初始化时,此列表的第一项path [0]是包含用于调用Python解释器的脚本的目录.如果脚本目录不可用(例如,如果以交互方式调用解释器或者从标准输入读取脚本),path [0]是空字符串,它指示Python首先搜索当前目录中的模块.请注意,在作为PYTHONPATH结果插入的条目之前插入了脚本目录.

sys.path [0]正是您要找的.


并且对于文件的完整路径:`os.path.join(sys.path [0],'some file.txt')`.这应该在所有系统上正确处理空格和斜线.

3> Zimm3r..:

好的,这就是我的工作

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.path,特别是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]为您提供始终从解释器运行的文件.根据您的需求,您需要选择最适合您需求的产品.


这是一个详尽的证据,表明实现反映了文档.`__file__`是*假设*为"总是给你当前文件的路径",而`sys.argv [0]`是*假设*为"总是给出启动过程的脚本的路径".在任何情况下,在被调用的脚本中使用`__file__`总能为您提供精确的结果.
推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有