我也会尝试解决这个问题的一些变化:
- 找到被调用脚本的路径
- 查找当前执行脚本的路径
- 找到被调用脚本的目录
(其中一些问题已在 SO 上提出,但已作为重复项关闭并在此处重定向。)
使用__file__ 的注意事项
对于您已导入的模块:
import something
something.__file__
将返回模块的绝对路径。但是,鉴于以下脚本 foo.py:
#foo.py
print '__file__', __file__
用'python foo.py'调用它会简单地返回'foo.py'。如果添加 shebang:
#!/usr/bin/python
#foo.py
print '__file__', __file__
并使用 ./foo.py 调用它,它将返回 './foo.py'。从不同的目录调用它,(例如将 foo.py 放在目录栏中),然后调用其中一个
python bar/foo.py
或添加shebang并直接执行文件:
bar/foo.py
将返回“bar/foo.py”(相对路径)。
查找目录
现在从那里获取目录,os.path.dirname(__file__) 也可能很棘手。至少在我的系统上,如果您从与文件相同的目录中调用它,它会返回一个空字符串。例如。
# foo.py
import os
print '__file__ is:', __file__
print 'os.path.dirname(__file__) is:', os.path.dirname(__file__)
将输出:
__file__ is: foo.py
os.path.dirname(__file__) is:
换句话说,它返回一个空字符串,所以如果你想将它用于当前的文件(而不是文件的文件一个导入的模块)。为了解决这个问题,您可以将其包装在对 abspath 的调用中:
# foo.py
import os
print 'os.path.abspath(__file__) is:', os.path.abspath(__file__)
print 'os.path.dirname(os.path.abspath(__file__)) is:', os.path.dirname(os.path.abspath(__file__))
输出类似:
os.path.abspath(__file__) is: /home/user/bar/foo.py
os.path.dirname(os.path.abspath(__file__)) is: /home/user/bar
注意 abspath() 不能解析符号链接。如果您想这样做,请改用 realpath()。例如,创建一个指向 file_import_testing.py 的符号链接 file_import_testing_link,其内容如下:
import os
print 'abspath(__file__)',os.path.abspath(__file__)
print 'realpath(__file__)',os.path.realpath(__file__)
执行将打印绝对路径,例如:
abspath(__file__) /home/user/file_test_link
realpath(__file__) /home/user/file_test.py
file_import_testing_link -> file_import_testing.py
使用检查
@SummerBreeze 提到使用inspect 模块。
对于导入的模块,这似乎效果很好,而且非常简洁:
import os
import inspect
print 'inspect.getfile(os) is:', inspect.getfile(os)
乖乖返回绝对路径。查找当前执行脚本的路径:
inspect.getfile(inspect.currentframe())
(感谢@jbochi)
inspect.getabsfile(inspect.currentframe())
给出当前执行脚本的绝对路径(感谢@Sadman_Sakib)。