使用Python获取当前脚本的名称

时间:2010-11-11 09:32:35

标签: python

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

例如,我有一个名为foo.py的脚本,我想在其中执行类似的操作:

print Scriptname

并获取:foo.py

18 个答案:

答案 0 :(得分:464)

使用__file__。如果要省略目录部分(可能存在),可以使用os.path.basename(__file__)

答案 1 :(得分:111)

import sys
print sys.argv[0]

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

答案 2 :(得分:56)

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

import __main__ as main
print(main.__file__)

请注意__main__.__file__适用于Python 2.7,但不适用于3.2,因此请使用上面的import-as语法使其可移植。

答案 3 :(得分:45)

为了完整起见,我认为总结各种可能的结果并为每种结果的确切行为提供参考是值得的:

  • __file__是当前正在执行的文件,详见official documentation

      

    __file__是加载模块的文件的路径名(如果是从文件加载的)。某些类型的模块可能缺少__file__属性,例如静态链接到解释器的 C 模块;对于从共享库动态加载的扩展模块,它是共享库文件的路径名。

    From Python3.4以后,每issue 18416__file__始终是绝对路径,除非当前正在执行的文件是直接执行的脚本(不是通过{{{ 1}}命令行选项)使用相对路径。

  • -m(需要导入__main__.__file__)只需访问main module的上述__main__属性,例如从命令行调用的脚本。

  • __file__(需要导入sys.argv[0])是从命令行调用的脚本名称,可能是绝对路径,详见official documentation:< / p>

      

    sys是脚本名称(无论这是否是完整路径名,它依赖于操作系统)。如果使用解释器的argv[0]命令行选项执行命令,则-c将设置为字符串argv[0]。如果没有脚本名称传递给Python解释器,'-c'是空字符串。

    another answer to this question中所述,通过py2exePyInstaller等工具转换为独立可执行程序的 Python 脚本可能无法显示所需内容使用此方法时的结果(即argv[0]将保存可执行文件的名称,而不是该可执行文件中主 Python 文件的名称。)

可以在上述任何一个上调用

sys.argv[0]以提取实际文件名。

答案 4 :(得分:36)

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

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

答案 5 :(得分:6)

试试这个:

print __file__

答案 6 :(得分:6)

sys中的第一个参数将是当前文件名,因此可以使用

   import sys
   print sys.argv[0] # will print the file name

答案 7 :(得分:5)

如果您正在进行异常导入(例如,它是一个选项文件),请尝试:

import inspect
print (inspect.getfile(inspect.currentframe()))

请注意,这将返回文件的绝对路径。

答案 8 :(得分:5)

对于现代Python版本,Path(__file__).name应该更加惯用。另外,Path(__file__).stem会为您提供不带.py扩展名的脚本名称。

答案 9 :(得分:5)

假设文件名是int,则下面的代码段

foo.py

import sys
print sys.argv[0][:-3]

将输出import sys print sys.argv[0][::-1][3:][::-1]

答案 10 :(得分:3)

我们可以尝试此操作以获取不带扩展名的当前脚本名称。

import os

script_name = os.path.splitext(os.path.basename(__file__))[0]

答案 11 :(得分:2)

从Python 3.5开始,您可以轻松做到:

from pathlib import Path
Path(__file__).stem

在此处查看更多信息:https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem

例如,我的用户目录下有一个名为test.py的文件,其内部为:

from pathlib import Path

print(Path(__file__).stem)
print(__file__)

运行以下输出:

>>> python3.6 test.py
test
test.py

答案 12 :(得分:2)

所有这些答案都很不错,但存在一些问题,您乍一看可能看不到。

let定义了我们想要的-我们想要执行的脚本的名称,而不是当前模块的名称-因此__file__仅在已执行的脚本中使用,而不在导入的脚本中使用时才有效模块。 sys.argv也值得怀疑-如果您的程序被pytest调用了怎么办?还是pydocRunner?还是被uwsgi调用?

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

另一个问题是,您(或某些其他程序)可以篡改sys.argv__main__.__file__-它可能​​存在,但可能没有。它可能有效或无效。至少您可以检查脚本(期望的结果)是否存在!

lib_programname正是这样做的:

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

通过这种方式,到目前为止,我的解决方案可以与setup.py testuwsgipytestpycharm pytestpycharm docrunner (doctest)dreampieeclipse

Dough Hellman上也有一篇有关该问题的不错的博客文章,“用Python确定进程的名称”

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

所以我宁愿照顾一个小模块,而不是在需要更改代码的情况下浏览我的代码库...


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

答案 13 :(得分:1)

由于OP要求提供当前脚本文件的名称,所以

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

答案 14 :(得分:0)

我的快速解决方案:

__file__.split('/')[-1:][0]

答案 15 :(得分:0)

os.path.abspath(__file__)将为您提供绝对路径(relpath()也可用)。

sys.argv[-1]将为您提供相对路径。

答案 16 :(得分:0)

您可以执行此操作而无需导入os或其他库。

如果要获取当前python脚本的路径,请使用:__file__

如果只想获取不带.py扩展名的文件名,请使用以下命令:

__file__.rsplit("/", 1)[1].split('.')[0]

答案 17 :(得分:-2)

 def basename():
   x=__file__
   y=x.split('\\')
   y1=y[-1]
   y2=y1.split('.')
   y3=y2[0]
 return(y2[0])
  
相关问题