我正在尝试获取当前正在运行的Python脚本的名称。
我有一个名为foo.py
的脚本,我想这样做以获取脚本名称:
print(Scriptname)
异常 NameError: NameError("全局名称 '__file__' 未定义",)
" - sdaau__file__
未定义,因为它在那里没有意义。它是由导入实现设置的,因此,如果您使用非标准的导入机制,则可能也会取消设置。 - Sven Marnachimport os
才能使其正常运行。我会将此添加到答案中。 - Nick Chammasimport sys
print(sys.argv[0])
这将会打印出python foo.py
的foo.py
,python dir/foo.py
的dir/foo.py
等。它是传递给python
的第一个参数。(请注意,在py2exe之后,它将变成foo.exe
。)
python linkfile.py
,其中linkfile.py
是指向realfile.py
的符号链接,sys.argv[0]
将会是'linkfile.py'
,这也许不是你想要的,但却是我预期的。__file__
同理:它将是linkfile.py
。如果你想从'linkfile.py'
中找到'realfile.py'
,可以尝试使用os.path.realpath('linkfile.py')
。 - Chris Morgan__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
提取没有后缀的实际文件名。
__file__
会给出此代码所在的文件,该文件可以被导入并且与正在解释的主文件不同。要获取主文件,可以使用特殊的__main__模块:import __main__ as main
print(main.__file__)
__main__.__file__
是可行的,但在3.2中不行,因此请使用上述导入语法来实现可移植性。rPython
包时就不行了。那一定是一个特殊情况,太难处理了。 - Leonid__main__
,用于在R
和Python
之间传递变量,因此在调用任何其他内容之前设置__main__.__file__
将是相对容易的,但我甚至不确定在这种情况下什么是适当的值。 - Perkinsimport sys
import os
file_name = os.path.basename(sys.argv[0])
对于现代 Python 版本(3.4+),Path(__file__).name
应该更符合习惯用法。此外,Path(__file__).stem
可以让你获得脚本名称但不包括 .py
扩展名。
from pathlib import Path
。 - Emil Melnikovpathlib
在 Python 3.4 中被引入,因此它应该从 Python 3.4 开始就可以使用。 - Andrey Semakin__file__
而不是file - Fermi-4如果你正在进行一次不寻常的导入(例如,它是一个选项文件),请尝试:
import inspect
print (inspect.getfile(inspect.currentframe()))
请注意,这将返回文件的绝对路径。
env.SConscript
调用当前文件时,以下内容最终有效。 - Adarsha从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
试试这个:
print __file__
__file__
如果你只想获取没有.py扩展名的文件名,请使用以下代码:__file__.rsplit("/", 1)[1].split('.')[0]
Path(__file__).name
表示获取当前文件的文件名(不包含路径)。 - aderchox