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

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

print(Scriptname)

当前回答

为了完整起见,我认为有必要总结各种可能的结果,并为每种结果的确切行为提供参考。

答案由四个部分组成:

返回当前执行脚本的完整路径的不同方法的列表。 关于处理相对路径的警告。 关于符号链接处理的建议。 说明了一些方法,这些方法可用于从完整的文件路径中提取实际文件名(带或不带后缀)。


提取完整的文件路径

__file__ is the currently executing file, as detailed in the official documentation: __file__ is the pathname of the file from which the module was loaded, if it was loaded from a file. The __file__ attribute may be missing for certain types of modules, such as C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file. From Python3.4 onwards, per issue 18416, __file__ is always an absolute path, unless the currently executing file is a script that has been executed directly (not via the interpreter with the -m command line option) using a relative path. __main__.__file__ (requires importing __main__) simply accesses the aforementioned __file__ attribute of the main module, e.g. of the script that was invoked from the command line. From Python3.9 onwards, per issue 20443, the __file__ attribute of the __main__ module became an absolute path, rather than a relative path. sys.argv[0] (requires importing sys) is the script name that was invoked from the command line, and might be an absolute path, as detailed in the official documentation: argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string. As mentioned in another answer to this question, Python scripts that were converted into stand-alone executable programs via tools such as py2exe or PyInstaller might not display the desired result when using this approach (i.e. sys.argv[0] would hold the name of the executable rather than the name of the main Python file within that executable). If none of the aforementioned options seem to work, probably due to an atypical execution process or an irregular import operation, the inspect module might prove useful, as suggested in another answer to this question: import inspect source_file_path = inspect.getfile(inspect.currentframe()) However, inspect.currentframe() would raise an exception when running in an implementation without Python stack frame. Note that inspect.getfile(...) is preferred over inspect.getsourcefile(...) because the latter raises a TypeError exception when it can determine only a binary file, not the corresponding source file (see also this answer to another question). From Python3.6 onwards, and as detailed in another answer to this question, it's possible to install an external open source library, lib_programname, which is tailored to provide a complete solution to this problem. This library iterates through all of the approaches listed above until a valid path is returned. If all of them fail, it raises an exception. It also tries to address various pitfalls, such as invocations via the pytest framework or the pydoc module. import lib_programname # this returns the fully resolved path to the launched python program path_to_program = lib_programname.get_path_executed_script() # type: pathlib.Path


处理相对路径

当处理一个恰好返回相对路径的方法时,可能很容易调用各种路径操作函数,例如os.path.abspath(…)或os.path.realpath(…),以便提取完整或真实的路径。

但是,这些方法依赖于当前路径来获得完整路径。因此,如果程序首先更改当前工作目录,例如通过os.chdir(…),然后才调用这些方法,则它们将返回错误的路径。


处理符号链接

如果当前脚本是一个符号链接,那么上述所有操作都将返回符号链接的路径,而不是实际文件的路径,为了提取后者,应该调用os.path.realpath(…)。


提取实际文件名的进一步操作

Os.path.basename(…)可能会被调用在上述任何一个上以提取实际的文件名,os.path.splitext(…)可能会被调用在实际的文件名上以截断其后缀,如os.path.splitext(Os.path.basename(…))。

从Python 3.4开始,根据PEP 428, pathlib模块的PurePath类也可以用于上述任何一个。具体来说,pathlib.PurePath(…).name提取实际的文件名和pathlib.PurePath(…)。Stem提取不带后缀的实际文件名。

其他回答

import sys
print(sys.argv[0])

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

如果你正在做一个不寻常的导入(例如,它是一个选项文件),尝试:

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

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

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

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

我们可以尝试这样做,以获得当前的脚本名称没有扩展名。

import os

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

为了完整起见,我认为有必要总结各种可能的结果,并为每种结果的确切行为提供参考。

答案由四个部分组成:

返回当前执行脚本的完整路径的不同方法的列表。 关于处理相对路径的警告。 关于符号链接处理的建议。 说明了一些方法,这些方法可用于从完整的文件路径中提取实际文件名(带或不带后缀)。


提取完整的文件路径

__file__ is the currently executing file, as detailed in the official documentation: __file__ is the pathname of the file from which the module was loaded, if it was loaded from a file. The __file__ attribute may be missing for certain types of modules, such as C modules that are statically linked into the interpreter; for extension modules loaded dynamically from a shared library, it is the pathname of the shared library file. From Python3.4 onwards, per issue 18416, __file__ is always an absolute path, unless the currently executing file is a script that has been executed directly (not via the interpreter with the -m command line option) using a relative path. __main__.__file__ (requires importing __main__) simply accesses the aforementioned __file__ attribute of the main module, e.g. of the script that was invoked from the command line. From Python3.9 onwards, per issue 20443, the __file__ attribute of the __main__ module became an absolute path, rather than a relative path. sys.argv[0] (requires importing sys) is the script name that was invoked from the command line, and might be an absolute path, as detailed in the official documentation: argv[0] is the script name (it is operating system dependent whether this is a full pathname or not). If the command was executed using the -c command line option to the interpreter, argv[0] is set to the string '-c'. If no script name was passed to the Python interpreter, argv[0] is the empty string. As mentioned in another answer to this question, Python scripts that were converted into stand-alone executable programs via tools such as py2exe or PyInstaller might not display the desired result when using this approach (i.e. sys.argv[0] would hold the name of the executable rather than the name of the main Python file within that executable). If none of the aforementioned options seem to work, probably due to an atypical execution process or an irregular import operation, the inspect module might prove useful, as suggested in another answer to this question: import inspect source_file_path = inspect.getfile(inspect.currentframe()) However, inspect.currentframe() would raise an exception when running in an implementation without Python stack frame. Note that inspect.getfile(...) is preferred over inspect.getsourcefile(...) because the latter raises a TypeError exception when it can determine only a binary file, not the corresponding source file (see also this answer to another question). From Python3.6 onwards, and as detailed in another answer to this question, it's possible to install an external open source library, lib_programname, which is tailored to provide a complete solution to this problem. This library iterates through all of the approaches listed above until a valid path is returned. If all of them fail, it raises an exception. It also tries to address various pitfalls, such as invocations via the pytest framework or the pydoc module. import lib_programname # this returns the fully resolved path to the launched python program path_to_program = lib_programname.get_path_executed_script() # type: pathlib.Path


处理相对路径

当处理一个恰好返回相对路径的方法时,可能很容易调用各种路径操作函数,例如os.path.abspath(…)或os.path.realpath(…),以便提取完整或真实的路径。

但是,这些方法依赖于当前路径来获得完整路径。因此,如果程序首先更改当前工作目录,例如通过os.chdir(…),然后才调用这些方法,则它们将返回错误的路径。


处理符号链接

如果当前脚本是一个符号链接,那么上述所有操作都将返回符号链接的路径,而不是实际文件的路径,为了提取后者,应该调用os.path.realpath(…)。


提取实际文件名的进一步操作

Os.path.basename(…)可能会被调用在上述任何一个上以提取实际的文件名,os.path.splitext(…)可能会被调用在实际的文件名上以截断其后缀,如os.path.splitext(Os.path.basename(…))。

从Python 3.4开始,根据PEP 428, pathlib模块的PurePath类也可以用于上述任何一个。具体来说,pathlib.PurePath(…).name提取实际的文件名和pathlib.PurePath(…)。Stem提取不带后缀的实际文件名。