__file__ 变量是啥意思/做啥?
Posted
技术标签:
【中文标题】__file__ 变量是啥意思/做啥?【英文标题】:what does the __file__ variable mean/do?__file__ 变量是什么意思/做什么? 【发布时间】:2012-03-05 12:01:14 【问题描述】:import os
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
模块,以便我可以开始使用它。
【问题讨论】:
【参考方案1】:当从 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
等)运行它,看看有什么不同。
【讨论】:
好答案,但从其他答案中查看其他重要细节:__file__
并非在所有情况下都定义,例如静态链接的 C 模块。我们不能指望__file__
始终可用。
在解释器中,所有的例子都返回name '__file__' is not defined
。
@user1063287 看DemoUser的回答; __file__
是加载模块的文件的路径名,如果它是从文件加载的。这意味着__file__
仅在您将其作为不在解释器中的脚本运行时才有效。(除非您在解释器中导入它...)【参考方案2】:
我只想先解决一些困惑。 __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
【讨论】:
【参考方案3】:根据documentation:
__file__
是模块所在文件的路径名 加载,如果它是从文件加载的。__file__
属性不是 用于静态链接到解释器的 C 模块; 对于从共享库动态加载的扩展模块,它是 共享库文件的路径名。
和also:
__file__
将成为文件的“路径”,除非模块是内置的(因此在sys.builtin_module_names
中列出),在这种情况下属性未设置。
【讨论】:
【参考方案4】:只是在这里添加一个简短的注释(主要是回答问题的标题而不是它的描述)关于可能会使某些人感到困惑的更改。从 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
【讨论】:
【参考方案5】:将__file__
与各种os.path
模块结合使用可以让所有路径都相对于当前模块的目录位置。这使您的模块/项目可以移植到其他机器上。
在你的项目中你这样做:
A = '/Users/myname/Projects/mydevproject/somefile.txt'
然后尝试使用诸如/home/web/mydevproject/
之类的部署目录将其部署到您的服务器,然后您的代码将无法正确找到路径。
【讨论】:
以上是关于__file__ 变量是啥意思/做啥?的主要内容,如果未能解决你的问题,请参考以下文章