如何使用Python查找脚本的目录?

Jon*_*han 451 python directory django-views getcwd

请考虑以下Python代码:

import os
print os.getcwd()
Run Code Online (Sandbox Code Playgroud)

os.getcwd()用来获取脚本文件的目录位置.当我从命令行运行脚本时它给了我正确的路径,而当我从Django视图中的代码运行的脚本运行它时,它会打印出来/.

如何从Django视图运行的脚本中获取脚本的路径?

更新:
总结到目前为止的答案 - os.getcwd()并且os.path.abspath()都给出当前工作目录,该目录可能是也可能不是脚本所在的目录.在我的网站主机设置中__file__只提供没有路径的文件名.

在Python中没有任何方法(总是)能够接收脚本所在的路径吗?

Cza*_*zak 708

你需要调用os.path.realpath__file__,这样,当__file__是一个文件名不带路径,你仍然可以获得目录路径:

import os
print(os.path.dirname(os.path.realpath(__file__)))
Run Code Online (Sandbox Code Playgroud)

  • 如果你从解释器内部运行,这将无法工作,因为你将得到`NameError:name'__ file__'未定义 (43认同)
  • 我认为这是预期的行为,因为python命令不存在于文件中,而是存在于传递给解释器的字符串中 (37认同)
  • @EhteshChoudhury那是因为`__file__`是一个只在执行脚本时创建的模块变量 - >这个变量代表脚本的位置.解释器不是从文件运行的,因此它不能有这样的变量. (6认同)
  • 迈克,怎么回事?`os.path.dirname(os.path.realpath(__ file __))== sys.path [0]`它们是相同的. (5认同)
  • 此解决方案给出了当前文件的目录。如果这是一个包中的模块(即脚本目录的子目录),它与脚本目录*不同*。如果需要后者,请改用`sys.path[0]`。要尝试它,让 `t/foo.py` 打印两个值和只包含 `import t.foo` 的 `bar.py`。 (4认同)
  • 尝试运行`python -c'import os; print os.path.dirname(os.path.realpath(__ file __))'`,这是一组由python解释器运行的命令. (2认同)
  • 这个答案是错误的。使用sys.path [0] (2认同)

RED*_*KEY 159

试试sys.path[0].

引用Python文档:

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

资料来源:https://docs.python.org/library/sys.html#sys.path

  • @thang通常,它会,但是这将返回正在运行的脚本的文件路径,而不是被调用脚本的目录.换句话说,如果我从`/ foo/bar.py`调用脚本`/ baz.py`,这个解决方案将返回`/ foo`而不是所需的`/`. (10认同)

neu*_*uro 131

我用:

import os
import sys

def get_script_path():
    return os.path.dirname(os.path.realpath(sys.argv[0]))
Run Code Online (Sandbox Code Playgroud)

正如aiham在评论中指出的那样,您可以在模块中定义此函数并在不同的脚本中使用它.

  • +1因为并不总是定义有用的`__file__`模块属性. (9认同)
  • 如果要将getScriptPath()放在不同的模块中,但获取实际执行的文件的路径而不是模块路径,这也很有用. (4认同)
  • argv [0]不是查找脚本路径/文件名的可靠方法.它可以是符号链接的名称,也可以是传递给execve(2)系统调用的任何其他内容. (3认同)

小智 18

这段代码:

import os
dn = os.path.dirname(os.path.realpath(__file__))
Run Code Online (Sandbox Code Playgroud)

将"dn"设置为包含当前正在执行的脚本的目录的名称.这段代码:

fn = os.path.join(dn,"vcb.init")
fp = open(fn,"r")
Run Code Online (Sandbox Code Playgroud)

将"fn"设置为"script_dir/vcb.init"(以独立于平台的方式)并打开该文件以供当前正在执行的脚本读取.

请注意,"当前正在执行的脚本"有些模棱两可.如果您的整个程序包含1个脚本,那么这是当前正在执行的脚本,并且"sys.path [0]"解决方案正常工作.但是如果你的应用程序包含脚本A,它导入一些包"P"然后调用脚本"B",那么"PB"当前正在执行.如果需要获取包含"PB"的目录,则需要" os.path.realpath(__file__)"解决方案.

" __file__"只给出当前正在执行的(栈顶)脚本的名称:"x.py".它不提供任何路径信息.这是执行实际工作的"os.path.realpath"调用.


jbc*_*tin 15

import os,sys
# Store current working directory
pwd = os.path.dirname(__file__)
# Append current directory to the python path
sys.path.append(pwd)
Run Code Online (Sandbox Code Playgroud)


Jon*_*han 7

os.path.abspath('')


Dan*_*n R 7

这对我有用(我通过这个stackoverflow问题找到了它)

os.path.realpath(__file__)
Run Code Online (Sandbox Code Playgroud)


beo*_*ver 7

import os
script_dir = os.path.dirname(os.path.realpath(__file__)) + os.sep
Run Code Online (Sandbox Code Playgroud)