A = os.path.join(os.path.dirname(__file__), '..')
B = os.path.dirname(os.path.realpath(__file__))
C = os.path.abspath(os.path.dirname(__file__))
我通常只是用实际路径硬连接这些。但是这些语句在运行时确定路径是有原因的,我真的很想理解os.path模块,所以我可以开始使用它。
答案 0 :(得分:113)
在Python中加载模块时,__file__
设置为其名称。然后,您可以将其与其他函数一起使用,以查找该文件所在的目录。
一次举一个例子:
A = os.path.join(os.path.dirname(__file__), '..')
# A is the parent directory of the directory where program resides.
B = os.path.dirname(os.path.realpath(__file__))
# B is the canonicalised (?) directory where the program resides.
C = os.path.abspath(os.path.dirname(__file__))
# C is the absolute path of the directory where the program resides.
您可以在此处看到从这些值返回的各种值:
import os
print __file__
print os.path.join(os.path.dirname(__file__), '..')
print os.path.dirname(os.path.realpath(__file__))
print os.path.abspath(os.path.dirname(__file__))
并确保您从不同的位置(例如./text.py
,~/python/text.py
等)运行它,看看它有什么不同。
答案 1 :(得分:44)
我只想先解决一些困惑。 __file__
不是通配符,而是属性。根据惯例,双下划线属性和方法被认为是“特殊的”并且用于特殊目的。
http://docs.python.org/reference/datamodel.html显示了许多特殊方法和属性,如果不是全部的话。
在这种情况下,__file__
是模块(模块对象)的属性。在Python中,.py
文件是一个模块。因此import amodule
将具有__file__
属性,这意味着在不同情况下会有不同的事情。
取自文档:
__file__
是加载模块的文件的路径名(如果是从文件加载的)。__file__
属性不存在 对于静态链接到解释器的C模块;对于 从共享库动态加载的扩展模块,它是 共享库文件的路径名。
在您的情况下,模块正在全局命名空间中访问它自己的__file__
属性。
要查看此操作,请尝试:
# file: test.py
print globals()
print __file__
并运行:
python test.py
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py
答案 2 :(得分:21)
__file__
是模块所在文件的路径名 如果从文件加载,则加载。__file__
属性不是 存在静态链接到解释器的C模块; 对于从共享库动态加载的扩展模块,它是 共享库文件的路径名。
和also:
__file__
将成为文件的“路径”,除非模块是内置的(因此在sys.builtin_module_names
中列出),在这种情况下,属性未设置。
答案 3 :(得分:10)
使用__file__
结合各种os.path
模块,可以使所有路径相对于当前模块的目录位置。这使您的模块/项目可以移植到其他机器上。
在您的项目中,您可以:
A = '/Users/myname/Projects/mydevproject/somefile.txt'
然后尝试使用/home/web/mydevproject/
等部署目录将其部署到您的服务器,那么您的代码将无法正确找到路径。
答案 4 :(得分:5)
只需在此处添加简短说明(主要是回答问题的标题而不是其描述),以了解可能会使某些人感到困惑的更改。从Python 3.4开始,__file__
的行为已发生了细微变化:
现在,默认情况下,模块
__file__
的属性(和相关值)应始终包含绝对路径,只有在使用相对路径直接执行脚本时,__main__.__file__
才是唯一的例外。 (由Brett Cannon在issue 18416中贡献。)
示例:
直接调用模块x和间接调用模块y:
# x.py:
from pathlib import Path
import y
print(__file__)
print(Path(__file__))
print(Path(__file__).resolve())
# y.py:
from pathlib import Path
print(__file__)
print(Path(__file__))
运行python3 x.py
将输出:
/home/aderchox/mytest/y.py
/home/aderchox/mytest/y.py
x.py
x.py
/home/aderchox/mytest/x.py