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

Sub*_*niC 344 python scripting basename

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

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

print Scriptname
Run Code Online (Sandbox Code Playgroud)

得到:foo.py.

Sve*_*ach 534

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

  • Python 3.2:"`异常NameError:NameError("全局名称'__file__'未定义",)`" (15认同)
  • @sdaau:`__file__`没有在交互式解释器中定义,因为它在那里没有意义.它由导入实现设置,因此如果您使用非标准导入机制,它也可能未设置. (14认同)
  • @ cdunn2001:`import os`和`import os.path`是完全等价的. (13认同)
  • 至少对于Python 2.7,我认为这需要`import os`才能工作.我将此添加到答案中. (8认同)
  • @sven-marnach:哦,[你说得对](http://stackoverflow.com/questions/2724348/should-i-use-import-os-path-or-import-os)。多年来我一直做错了! (2认同)
  • 我想出了一行: `filename = __file__.split('/')[-1]` 或 `filetitle = __file__.split('/')[-1].split('.') [0]` (2认同)

Chr*_*gan 121

import sys
print sys.argv[0]
Run Code Online (Sandbox Code Playgroud)

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

  • @DenisMalinovsky:定义"不会起作用".如果你调用`python linkfile.py`,其中`linkfile.py`是`realfile.py`的符号链接,`sys.argv [0]`将是''linkfile.py'`,这可能是也可能不是你想要什么; 这肯定是我期望的*.`__file__`是相同的:它将是`linkfile.py`.如果你想从''linkfile.py'找到''realfile.py'`,试试`os.path.realpath('linkfile.py')`. (32认同)
  • +1因为它是(a)有点整洁,(b)仍然可以在模块中工作(其中__file__变量是模块文件,而不是执行的模块文件). (6认同)
  • 什么!!!你试过这个吗?事实恰恰相反。提问者询问正在运行的 python 脚本的名称 - 而不是当前正在执行的 python 文件。想象一下,您有一个脚本,当发生错误时,它会打印脚本名称以及允许的参数。您可以使用这两种技术之一将其放入函数中。在某些时候,您决定将该函数移至外部库。您想打印正在运行的主脚本的名称,还是正在执行的库文件的名称? (3认同)
  • 当您想要打印出使用信息时,这是正确的解决方案,因为这正是程序的调用方式,而 __file__ 不是。 (3认同)

Amb*_*jak 63

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

import __main__ as main
print(main.__file__)
Run Code Online (Sandbox Code Playgroud)

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


Yoe*_*oel 57

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

  • __file__是当前正在执行的文件,详见官方文档:

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

    从Python3.4起,每发行18416,__file__始终是一个绝对路径,除非当前正在执行的文件是已经被直接执行(不通过与解释脚本-m使用相对路径命令行选项).

  • __main__.__file__(需要导入__main__)只需访问主模块的上述__file__属性,例如从命令行调用的脚本.

  • sys.argv[0](需要导入sys)是从命令行调用的脚本名称,可能是绝对路径,如官方文档中所述:

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

    正如提到的另一个回答这个问题,Python的是被通过的工具,如转换成独立的可执行程序的脚本py2exePyInstaller使用这种方法时,可能不会显示期望的结果(即sys.argv[0]将举行的可执行文件的名称,而不是名称该可执行文件中的主要Python文件).


inspect.getfile() 可以在上述任何一个上调用,以便提取实际的文件名.


Man*_*ahu 40

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

import sys    
import os    
file_name =  os.path.basename(sys.argv[0])
Run Code Online (Sandbox Code Playgroud)

  • 我也喜欢拆分扩展名,所以我使用: os.path.splitext(os.path.basename(sys.argv[0]))[0] (2认同)

Emi*_*kov 12

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

  • 您应该先“从pathlib导入Path”。 (4认同)
  • @einpoklum `pathlib` 是在 Python 3.4 中引入的,所以它应该从 Python 3.4 开始工作。 (2认同)

小智 8

我们可以尝试这样做来获取当前的脚本名称,不带扩展名。

import os

script_name = os.path.splitext(os.path.basename(__file__))[0]
Run Code Online (Sandbox Code Playgroud)


The*_*nil 8

您可以在不导入操作系统或其他库的情况下执行此操作。

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

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

__file__.rsplit("/", 1)[1].split('.')[0]
Run Code Online (Sandbox Code Playgroud)


Cha*_*nor 7

sys中的第一个参数将是当前文件名,因此这将起作用

   import sys
   print sys.argv[0] # will print the file name
Run Code Online (Sandbox Code Playgroud)


xto*_*sou 7

假设文件名是foo.py,下面的代码片段

import sys
print sys.argv[0][:-3]
Run Code Online (Sandbox Code Playgroud)

要么

import sys
print sys.argv[0][::-1][3:][::-1]
Run Code Online (Sandbox Code Playgroud)

将输出 foo.pypy


Gaj*_*mbi 6

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

import inspect
print (inspect.getfile(inspect.currentframe()))
Run Code Online (Sandbox Code Playgroud)

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


ela*_*ver 5

从 Python 3.5 开始,您可以简单地执行以下操作:

from pathlib import Path
Path(__file__).stem
Run Code Online (Sandbox Code Playgroud)

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

例如,我的用户目录下有一个文件,test.py里面用这个命名:

from pathlib import Path

print(Path(__file__).stem)
print(__file__)
Run Code Online (Sandbox Code Playgroud)

运行此输出:

>>> python3.6 test.py
test
test.py
Run Code Online (Sandbox Code Playgroud)