考虑下面的python代码:
1 2
| import os
print os.getcwd() |
我使用os.getcwd()获取脚本文件的目录位置。当我从命令行运行脚本时,它给出了正确的路径,而当我从Django视图中的代码运行脚本时,它会打印/。
如何从Django视图运行的脚本中获取脚本的路径?
更新:总结到目前为止的答案——os.getcwd()和os.path.abspath()都给出了当前的工作目录,这个目录可能是脚本所在的目录,也可能不是。在我的web主机设置中,__file__只给出没有路径的文件名。
难道在Python中没有任何方法(总是)能够接收脚本所在的路径吗?
- 你应该更仔细地阅读那篇链接文章。它从不建议使用getcwd来告诉您脚本的位置。建议采用argv[0]、dirname和abspath。
- @rob-"print sys.argv[0]"在我的web主机上只给出文件名,没有路径
- @Rob-以下是链接文章"os.getcwd()返回当前工作目录"的摘录。
- 是的,但是当前的工作目录与脚本所在的目录完全没有关系。与设置当前工作目录的os.chdir相比,它不会将脚本文件移动到硬盘上的新位置。初始工作目录可能与脚本所在的目录相同,但并不总是相同;本文甚至演示了这一点。
- @罗布-抓得好,我的错:)
- 注意,__file__将返回脚本上下文的文件名。注意:如果你从你的__main__调用一个外部脚本,你可能会得到一个不同于你预期的响应。
- JFS?什么文章的副本?当您将某个内容标记为重复项时,so.ui是否允许您指定链接?
您需要在__file__上调用os.path.realpath,这样当__file__是一个没有路径的文件名时,您仍然可以得到dir路径:
1 2
| import os
print(os.path.dirname(os.path.realpath(__file__))) |
- 如果你从一个解释程序内部运行,这将不起作用,因为你会得到NameError: name '__file__' is not defined。
- @你说的running from inside an interpreter是什么意思?
- 尝试运行python -c 'import os; print os.path.dirname(os.path.realpath(__file__))',这是一组由Python解释器运行的命令。
- 我认为这是预期的行为,因为python命令不存在于文件中,而是在传递给解释器的字符串中。
- @ehteshchoudhury,这是因为__file__是一个模块变量,只有在执行脚本时才创建该变量->该变量表示脚本的位置。解释器不是从文件运行的,所以它不能有这样的变量。
- 这个答案是错误的。使用sys .PATH [ 0 ]
- 迈克,怎么了?它们是相同的。
- 也要小心os.chdir()。在下面,该行为相当于将当前工作目录与__file__的相对路径连接起来。
- @迈克,你能更好地解释为什么答案是错误的吗?
- 语法错误:无效语法
- 此解决方案提供当前文件的目录。如果这是包中的一个模块(即,脚本的目录的子目录),则它与脚本的目录不同。如果需要后者,则使用sys.path[0]。尝试一下,让t/foo.py同时打印值和bar.py,其中只包含import t.foo。
试试sys.path[0]。
引用python文档:
As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter. If the script directory is not available (e.g. if the interpreter is invoked interactively or if the script is read from standard input), path[0] is the empty string, which directs Python to search modules in the current directory first. Notice that the script directory is inserted before the entries inserted as a result of PYTHONPATH.
来源:https://docs.python.org/library/sys.html sys.path
- 这通常是正确的解决方案
- 这是正确的解决方案。
- 是的,这是正确的解决方案。公认的解决方案是垃圾。
- @它通常是,但这会返回正在运行的脚本的文件路径,而不是被调用脚本的目录。换句话说,如果我从/foo/bar.py调用脚本/baz.py,这个解决方案将返回/foo,而不是所需的/。
- 我在这个解决方案中遇到了一个问题。我正在构建一个名为foo的大型程序,其中主脚本名为__main__.py并位于foo目录中。我可以通过运行python foo/__main__.py来调用我的程序,也可以简单地运行python foo。对于前者,您的解决方案是有效的,但是对于后者,我以相对路径而不是绝对路径结束。把你的解决方案包装在os.path.realpath()中解决了这个问题。
- 它们sys.argv[0]在一个案例中失败了:当用py2app将脚本包装到MacOS上的应用程序中时,当我所有的支持脚本都在EDOCX1[14]中时,sys.argv[0]就变成了一个硬编码的EDOCX1[13]。这可能是一个PY2Appbug,但它证明了依赖argv仍然有点脆弱。
- 我在我的bin目录中调用一个脚本作为符号链接,指向一个不在我路径中的可执行python文件。但是,sys.path[0]显示的是我的bin目录,而不是运行脚本的绝对路径。
- sys.path[0]是指运行位置脚本的位置,在大多数情况下,它与包含脚本的目录相同。现在,如果您将脚本编译成二进制文件,然后执行它,那么sys.path[0]将引用%temp%,因为exe是从temp运行的。至少在Windows上是这样。
我使用:
1 2 3 4 5
| import os
import sys
def get_script_path():
return os.path.dirname(os.path.realpath(sys.argv[0])) |
正如Aiham在注释中指出的,您可以在模块中定义这个函数,并在不同的脚本中使用它。
- +1,因为不总是定义有用的__file__模块属性。
- 如果要将getScriptPath()放在其他模块中,但要获取实际执行的文件的路径,而不是模块路径,则这一点也很有用。
- @艾哈姆:说得好。实际上,这个函数在我的framework utils模块中:)
- @艾哈姆:这在我使用virtualenv时似乎不起作用。我得到virtualenv的bin dir的路径,而不是调用getscriptpath()的.py文件。例如/home/vagrant/.virtualenvs/myvenv/bin/…对此有什么想法吗?
- 嗯,看看系统argv[1:……
- 只需注意,这将返回执行的python脚本的路径。如果您将这些代码作为包放在其他地方,那么这些代码将不会返回Python文件的源代码。
- argv[0]不是查找脚本路径/文件名的可靠方法。它可以是符号链接的名称,也可以是传递给execve(2)系统调用的任何其他名称。
- 我想要的是初始python程序的路径,而不是执行代码的树中其他模块的路径,所以这个解决方案是完美的。那些真正想要调用模块的路径的人应该使用__file__,而不是sys.argv[0]。
此代码:
1 2
| import os
dn = os.path.dirname(os.path.realpath(__file__)) |
将"dn"设置为包含当前执行脚本的目录名。此代码:
1 2
| fn = os.path.join(dn,"vcb.init")
fp = open(fn,"r") |
将"fn"设置为"script_dir/vcb.init"(以独立于平台的方式),然后打开当前正在执行的脚本要读取的文件。
注意,"当前正在执行的脚本"有点含糊不清。如果整个程序由1个脚本组成,那么这就是当前正在执行的脚本,"sys.path[0]"解决方案可以正常工作。但是如果你的应用程序由脚本A组成,它导入一些包"p",然后调用脚本"b",那么"p.b"当前正在执行。如果需要获取包含"p.b"的目录,则需要"os.path.realpath(__file__)解决方案。
"__file__只是给出了当前正在执行(堆栈顶部)脚本的名称:"x.py"。它不提供任何路径信息。真正有用的是"os.path.real path"调用。
1 2 3 4 5
| import os,sys
# Store current working directory
pwd = os.path.dirname(__file__)
# Append current directory to the python path
sys.path.append(pwd) |
- 这在我的dev机器上很好,但在我的web主机上不起作用-我得到了'/'
- 奇怪,您有权限访问apache conf文件吗?或者这是Windows服务器?
1 2
| import os
script_dir = os.path.dirname(os.path.realpath(__file__)) + os.sep |
这对我很有用(我通过这个stackoverflow问题找到了它)
1
| os.path.realpath(__file__) |
这就是我的结局。如果我在解释器中导入脚本,并且将其作为脚本执行,这对我很有用:
1 2 3 4 5 6 7 8 9 10
| import os
import sys
# Returns the directory the current script (or interpreter) is running in
def get_script_directory():
path = os.path.realpath(sys.argv[0])
if os.path.isdir(path):
return path
else:
return os.path.dirname(path) |
这是一个非常老的线程,但是当我试图将文件保存到脚本从cron作业运行python脚本时所在的当前目录中时,我遇到了这个问题。getcwd()和许多其他路径都会找到您的主目录。
获取我使用的脚本的绝对路径
directory = os.path.abspath(os.path.dirname(__file__))
使用os.path.abspath('')。
- 这适用于开发人员计算机上的所有内容,但仅适用于Web主机上的脚本文件。它不适用于settings.py,例如以下内容不起作用:template_dirs=(os.path.abspath('')+'/templates'),)
- 这对我不起作用。我通过路径中的符号链接调用一个可执行的python scdript(不在我的路径中)。它刚刚打印了我的垃圾箱目录。
- 真的。。。这适用于所有硬情况,例如从父文件夹或repl中启动的笔记本上运行。这应该是公认的答案!
试试这个:
1 2 3
| def get_script_path(for_file = None):
path = os.path.dirname(os.path.realpath(sys.argv[0] or 'something'))
return path if not for_file else os.path.join(path, for_file) |
1 2 3
| import os
exec_filepath = os.path.realpath(__file__)
exec_dirpath = exec_filepath[0:len(exec_filepath)-len(os.path.basename(__file__))] |
- 为什么不使用os.path.dirname?
- 我不知道os.path.dirname,也许也可以。