__file__ 变量的含义/作用是什么?
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 模块,以便我可以开始使用它。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
当从 Python 中的文件加载模块时,
__file__
将设置为其 绝对路径。然后,您可以将其与其他函数一起使用来查找文件所在的目录。一次一个示例:
您可以在此处看到从这些函数返回的各种值:
并确保从不同位置运行它(例如
./text.py
、~/python/text.py
等等)看看有什么区别。When a module is loaded from a file in Python,
__file__
is set to its absolute path. You can then use that with other functions to find the directory that the file is located in.Taking your examples one at a time:
You can see the various values returned from these here:
and make sure you run it from different locations (such as
./text.py
,~/python/text.py
and so forth) to see what difference that makes.我只想先解决一些困惑。
__file__
不是通配符,它是一个属性。按照惯例,双下划线属性和方法被认为是“特殊”的,并且有特殊的用途。http://docs.python.org/reference/datamodel.html 显示了许多特殊方法和属性,如果不是全部的话。
在本例中,
__file__
是模块(模块对象)的属性。在 Python 中,.py
文件是一个模块。所以import amodule
将会有一个__file__
属性,在不同的情况下意味着不同的东西。摘自文档:
在您的情况下,模块正在全局命名空间中访问它自己的 __file__ 属性。
要查看实际效果,请尝试:
并运行:
I just want to address some confusion first.
__file__
is not a wildcard it is an attribute. Double underscore attributes and methods are considered to be "special" by convention and serve a special purpose.http://docs.python.org/reference/datamodel.html shows many of the special methods and attributes, if not all of them.
In this case
__file__
is an attribute of a module (a module object). In Python a.py
file is a module. Soimport amodule
will have an attribute of__file__
which means different things under difference circumstances.Taken from the docs:
In your case the module is accessing it's own
__file__
attribute in the global namespace.To see this in action try:
And run:
根据文档:
以及还有:
Per the documentation:
and also:
只是在这里添加一个关于可能使某些人感到困惑的更改的快速注释(主要是回答问题的标题而不是其描述)。从 Python 3.4 开始,
__file__
的行为方式发生了细微变化:示例:
直接调用模块 x和模块 y 间接:
运行 python3 x.py 将输出:
Just going to add a quick note here (mostly answering the question's title rather than its description) about a change which can confuse some people. As of Python 3.4 there has been a slight change in how the
__file__
behaves:Example:
Calling module x directly and module y indirectly:
Running
python3 x.py
will output:将 __file__ 与各种 os.path 模块结合使用可以让所有路径相对于当前模块的目录位置。这允许您的模块/项目可以移植到其他机器。
在您的项目中,您执行以下操作:
然后尝试使用
/home/web/mydevproject/
之类的部署目录将其部署到服务器,然后您的代码将无法正确找到路径。Using
__file__
combined with variousos.path
modules lets all paths be relative the current module's directory location. This allows your modules/projects to be portable to other machines.In your project you do:
and then try to deploy it to your server with a deployments directory like
/home/web/mydevproject/
then your code won't be able to find the paths correctly.要添加到 aderchox 的答案中,
__file__
变量的行为在 Python 3.9 中再次更改,现在在所有情况下它都是绝对路径运行相同的示例(但将其复制到此处以实现自我一致性)
现在运行
x.py
具有两个不同版本的解释器源:
https://docs.python.org/3/whatsnew/3.9 .html#其他语言更改
To add to aderchox's answer, the behaviour of the
__file__
variable was again changed in Python 3.9, and now it's an absolute Path in all casesRunning the same example (but copying it here for self consistency)
Now running
x.py
with two different versions of the interpretersource:
https://docs.python.org/3/whatsnew/3.9.html#other-language-changes
使用死灵术
[仅在 PYTHON 3.7 中测试]
我使用:
与我见过的其他解决方案相比,我更喜欢它。我编写的一些测试代码:
输出:
请记住,如果 __file__ 使用除 os.sep 之外的任何分隔符(例如:os.altsep)返回字符串,则程序将失败。我没有受到这种影响,但谁知道这些天...
如果需要的话,您总是可以先在字符串中找到分隔符,然后使用它而不是 os.sep。根据时间复杂度标准(找到分离器的时间基本上是恒定的),速度的改进将保持不变。
Necromancy engaged
[ONLY TESTED IN PYTHON 3.7]
I use:
And I prefer it over the other solutions I've seen provided. Some test code I wrote:
Output:
Keep in mind that if __file__ returns a string using any separator (ex: os.altsep) other than os.sep, the program will fail. I haven't had this affect me, but who knows these days...
You could always find the separator in the string first if need be, then use that instead of os.sep. The speed improvements would, as per time complexity standards (time to find the separator is essentially constant), remain.
使用 pathlib.Path 处理此问题的最简单的“pythonic”方法是将其用作:
因为您可以直接使用“/”。
The most simple, "pythonic" way of handling this with pathlib.Path would be to use it as:
because you can use "/" directly.