关于python:查找当前运行文件的路径

Find path to currently running file

如何找到当前运行的python脚本的完整路径?也就是说,为了达到这个目标,我必须做些什么:

1
2
3
Nirvana@bahamut:/tmp$ python baz.py
running from /tmp
file is baz.py


你要找的不是__file__。不要使用意外的副作用

sys.argv[0]始终是脚本的路径(如果实际上调用了脚本)--请参见http://docs.python.org/library/sys.html sys.argv

__file__是当前执行文件(脚本或模块)的路径。如果从脚本访问该脚本,则它意外地与该脚本相同!如果要将有用的东西(如相对于脚本位置定位资源文件)放入库中,则必须使用sys.argv[0]

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
C:\junk\so>type \junk\so\scriptpath\script1.py
import sys, os
print"script: sys.argv[0] is", repr(sys.argv[0])
print"script: __file__ is", repr(__file__)
print"script: cwd is", repr(os.getcwd())
import whereutils
whereutils.show_where()

C:\junk\so>type \python26\lib\site-packages\whereutils.py
import sys, os
def show_where():
    print"show_where: sys.argv[0] is", repr(sys.argv[0])
    print"show_where: __file__ is", repr(__file__)
    print"show_where: cwd is", repr(os.getcwd())

C:\junk\so>\python26\python scriptpath\script1.py
script: sys.argv[0] is 'scriptpath\\script1.py'
script: __file__ is 'scriptpath\\script1.py'
script: cwd is 'C:\\junk\\so'
show_where: sys.argv[0] is 'scriptpath\\script1.py'
show_where: __file__ is 'C:\\python26\\lib\\site-packages\\whereutils.pyc'
show_where: cwd is 'C:\\junk\\so'


这将打印脚本所在的目录(而不是工作目录):

1
2
3
4
import os
dirname, filename = os.path.split(os.path.abspath(__file__))
print"running from", dirname
print"file is", filename

当我把它放到c:\src中时,它的行为如下:

1
2
3
4
5
6
7
8
9
> cd c:\src
> python so-where.py
running from C:\src
file is so-where.py

> cd c:\
> python src\so-where.py
running from C:\src
file is so-where.py


1
2
3
4
5
6
import sys, os

file = sys.argv[0]
pathname = os.path.dirname(file)
print 'running from %s' % os.path.abspath(pathname)
print 'file is %s' % file

检查os.getcwd()(docs)


我建议

1
2
import os, sys
print os.path.split(os.path.abspath(os.path.realpath(sys.argv[0])))[0]

这样,您就可以安全地创建指向脚本可执行文件的符号链接,它仍然可以找到正确的目录。


运行文件始终是__file__

这是一个名为identify.py的演示脚本

1
print __file__

这是结果

1
2
3
4
5
MacBook-5:Projects slott$ python StackOverflow/identify.py
StackOverflow/identify.py
MacBook-5:Projects slott$ cd StackOverflow/
MacBook-5:StackOverflow slott$ python identify.py
identify.py

脚本名将(始终?)作为sys.argv的第一个索引:

1
2
import sys
print sys.argv[0]

找到运行脚本路径的更简单方法:

1
os.path.dirname(sys.argv[0])


python正在执行的脚本目录被添加到sys.path中。这实际上是一个包含其他路径的数组(列表)。第一个元素包含脚本所在的完整路径(对于Windows)。

因此,对于Windows,可以使用:

1
2
3
import sys
path = sys.path[0]
print(path)

其他人建议使用sys.argv[0],它的工作方式非常相似,并且是完整的。

1
2
3
import sys
path = os.path.dirname(sys.argv[0])
print(path)

注意,sys.argv[0]包含完整的工作目录(路径)+文件名,而sys.path[0]是当前没有文件名的工作目录。

我已经在Windows上测试了sys.path[0],它工作正常。我还没有在Windows以外的其他操作系统上进行测试,因此可能有人对此发表评论。


除了上述的sys.argv[0]外,还可以使用__main__

1
2
import __main__
print(__main__.__file__)

然而,要小心,这只在非常罕见的情况下有用;它总是创建一个导入循环,这意味着此时__main__不会完全执行。