我正在尝试获取当前正在运行的Python脚本的名称。

我有一个名为foo.py的脚本,我想这样做,以便获得脚本名称:

print(Scriptname)

当前回答

以上答案很好。但我发现这种方法使用上述结果更有效。 这将导致实际的脚本文件名而不是路径。

import sys    
import os    
file_name =  os.path.basename(sys.argv[0])

其他回答

注意__file__将给出该代码所在的文件,该文件可以导入,并且与正在解释的主文件不同。要获取主文件,可以使用特殊的__main__模块:

import __main__ as main
print(main.__file__)

注意__main__。__file__在Python 2.7中有效,但在3.2中无效,因此使用上面的import-as语法使其可移植。

import sys
print(sys.argv[0])

这将为python打印foo.py,为python打印dir/foo.py,等等。它是python的第一个参数。(注意py2exe之后是foo.exe。)

所有的答案都很棒,但也有一些你第一眼可能看不出来的问题。

让我们定义我们想要的-我们想要执行的脚本的名称,而不是当前模块的名称-因此__file__只在已执行的脚本中使用,而不是在导入的模块中使用时才有效。 sys。Argv也是有问题的——如果你的程序是由pytest调用的呢?还是pydoc runner ?或者它是由uwsgi调用的?

还有第三种获取脚本名称的方法,我在答案中没有看到-你可以检查堆栈。

另一个问题是,你(或其他程序)可以篡改sys. exe。Argv和__main__。__file__ -它可能存在,也可能不存在。它可能成立,也可能不成立。至少您可以检查脚本(期望的结果)是否存在!

lib_programname库就是这样做的:

检查__main__是否存在 检查__main__。存在__file__ 给出__main__。__file__一个有效的结果(该脚本存在吗?) 如果不是:检查sys.argv: 系统中是否存在pytest, docrunner等。argv吗?——>如果是,忽略它 我们能得到一个有效的结果吗? 如果不是:检查堆栈,并尽可能从那里得到结果 如果堆栈也没有给出有效的结果,则抛出异常。

通过这种方式,我的解决方案到目前为止使用setup.py test, uwsgi, pytest, pycharm pytest, pycharm docrunner (doctest), dreampie, eclipse

Dough Hellman也有一篇关于这个问题的不错的博客文章,“从Python中确定进程的名称”。

顺便说一句,它将在python 3.9中再次改变:主模块的文件属性变成了绝对路径,而不是相对路径。在当前目录被os.chdir()更改后,这些路径仍然有效

所以我宁愿照顾一个小模块,而不是浏览我的代码库,如果它应该改变一些…


免责声明:我是lib_programname库的作者。

由于OP要求当前脚本文件的名称,我更喜欢

import os
os.path.split(sys.argv[0])[1]

对于现代Python版本(3.4+),Path(__file__).name应该更习惯。同时,路径(__file__)。Stem提供了不带.py扩展名的脚本名称。