如何获取当前执行的Python文件的路径和名称?
我有一些脚本会调用其他脚本文件,但我需要获取当前正在运行的文件的路径。
举个例子,假设我有三个文件。使用 execfile:
script_1.py
调用script_2.py
。- 然后,
script_2.py
又调用script_3.py
。
我该如何在script_3.py
中获取文件名和路径,而不需要从 script_2.py
传递这些信息作为参数呢?
(执行 os.getcwd()
会返回最开始启动的脚本的路径,而不是当前文件的路径。)
26 个回答
更新于2018-11-28:
这里总结了关于Python 2和3的一些实验。我们有以下文件:
main.py - 运行foo.py
foo.py - 运行lib/bar.py
lib/bar.py - 打印文件路径表达式
| Python | Run statement | Filepath expression |
|--------+---------------------+----------------------------------------|
| 2 | execfile | os.path.abspath(inspect.stack()[0][1]) |
| 2 | from lib import bar | __file__ |
| 3 | exec | (wasn't able to obtain it) |
| 3 | import lib.bar | __file__ |
对于Python 2,使用包会更清晰,可以用from lib import bar
来导入,只需在这两个文件夹里添加空的__init__.py
文件。
对于Python 3,execfile
这个功能不存在,最接近的替代方法是exec(open(<filename>).read())
,不过这会影响调用栈。最简单的做法是直接使用import foo
和import lib.bar
,不需要__init__.py
文件。
也可以查看 导入和execfile之间的区别
原始回答:
这是基于这个讨论串中的回答进行的实验 - 使用的是Windows上的Python 2.7.10。
基于栈的方式似乎是唯一能给出可靠结果的方法。最后两个方法的语法最简洁,也就是:
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
希望这些能作为函数添加到sys中!感谢@Usagi和@pablog
基于以下三个文件,并从其文件夹运行main.py,命令是python main.py
(也尝试过使用绝对路径的execfiles和从其他文件夹调用)。
C:\filepaths\main.py: execfile('foo.py')
C:\filepaths\foo.py: execfile('lib/bar.py')
C:\filepaths\lib\bar.py:
import sys
import os
import inspect
print "Python " + sys.version
print
print __file__ # main.py
print sys.argv[0] # main.py
print inspect.stack()[0][1] # lib/bar.py
print sys.path[0] # C:\filepaths
print
print os.path.realpath(__file__) # C:\filepaths\main.py
print os.path.abspath(__file__) # C:\filepaths\main.py
print os.path.basename(__file__) # main.py
print os.path.basename(os.path.realpath(sys.argv[0])) # main.py
print
print sys.path[0] # C:\filepaths
print os.path.abspath(os.path.split(sys.argv[0])[0]) # C:\filepaths
print os.path.dirname(os.path.abspath(__file__)) # C:\filepaths
print os.path.dirname(os.path.realpath(sys.argv[0])) # C:\filepaths
print os.path.dirname(__file__) # (empty string)
print
print inspect.getfile(inspect.currentframe()) # lib/bar.py
print os.path.abspath(inspect.getfile(inspect.currentframe())) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) # C:\filepaths\lib
print
print os.path.abspath(inspect.stack()[0][1]) # C:\filepaths\lib\bar.py
print os.path.dirname(os.path.abspath(inspect.stack()[0][1])) # C:\filepaths\lib
print
p1.py:
execfile("p2.py")
p2.py:
import inspect, os
print (inspect.getfile(inspect.currentframe())) # script filename (usually with path)
print (os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))) # script directory