__file__变量是什么意思/做什么?

dep*_*ing 140 python

A = os.path.join(os.path.dirname(__file__), '..')

B = os.path.dirname(os.path.realpath(__file__))

C = os.path.abspath(os.path.dirname(__file__))
Run Code Online (Sandbox Code Playgroud)

我通常只是用实际路径来硬连线.但是这些语句在运行时确定路径是有原因的,我真的很想了解os.path模块,所以我可以开始使用它.

pax*_*blo 131

在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.
Run Code Online (Sandbox Code Playgroud)

您可以在此处看到从这些返回的各种值:

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__)))
Run Code Online (Sandbox Code Playgroud)

并确保从不同的位置(例如./text.py,~/python/text.py等等)运行它,看看它有什么不同.

  • @ user1063287看看DemoUser的答案; `__file__`是从中加载模块的文件的路径名,如果它是从文件加载的.这意味着`__file__`只有当你作为脚本而不是在解释器中运行它时才会起作用.(除非你在解释器中导入它...) (8认同)
  • 很好的答案,但从其他答案中看到其他重要细节:`__ file__`并非在所有情况下都定义,例如静态链接的C模块.我们不能指望`__file__`始终可用. (6认同)
  • 在解释器中,所有示例都返回`name'__ file__'未定义`. (4认同)
  • “当从 Python 中的文件加载模块时,`__file__` 被设置为 __its__ 路径。” 谁的路?对不起,我的英语不好。我可以说 `__file__` 总是指向当前脚本/模块/文件吗? (2认同)

Der*_*itz 48

我只想先解决一些困惑. __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__
Run Code Online (Sandbox Code Playgroud)

并运行:

python test.py

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
 'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py
Run Code Online (Sandbox Code Playgroud)


Sud*_*oti 22

根据文件:

__file__是加载模块的文件的路径名,如果它是从文件加载的.__file__对于静态链接到解释器的C模块,该属性不存在; 对于从共享库动态加载的扩展模块,它是共享库文件的路径名.

:

__file__将成为文件的"路径",除非模块是内置的(并因此列在其中sys.builtin_module_names),在这种情况下,属性未设置.


ade*_*hox 12

只是要在这里添加一个简短的注释(主要是回答问题的标题而不是它的描述)关于可能使某些人感到困惑的更改。从 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__))
Run Code Online (Sandbox Code Playgroud)

运行python3 x.py会输出:

/home/aderchox/mytest/y.py                                                                                                                       
/home/aderchox/mytest/y.py                                                                                                                       
x.py                                                                                                                                             
x.py                                                                                                                                             
/home/aderchox/mytest/x.py
Run Code Online (Sandbox Code Playgroud)

  • 从Python 3.9开始,默认路径是绝对路径(参见/sf/answers/5205200871/)@Neutrinoceros (3认同)

Sam*_*lan 10

使用__file__具有各种组合的os.path模块允许所有路径是相对的当前模块的目录位置.这允许您的模块/项目可移植到其他机器.

在您的项目中,您可以:

A = '/Users/myname/Projects/mydevproject/somefile.txt'
Run Code Online (Sandbox Code Playgroud)

然后尝试使用部署目录将其部署到您的服务器,就像/home/web/mydevproject/那时您的代码将无法正确找到路径.


小智 9

为了添加 aderchox 的答案,变量的行为__file__在 Python 3.9 中再次发生变化,现在在所有情况下它都是绝对路径

运行相同的示例(但为了自我一致性而将其复制到此处)

# 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__))
Run Code Online (Sandbox Code Playgroud)

现在运行x.py两个不同版本的解释器

$ python3.8 x.py
/private/tmp/y.py
/private/tmp/y.py
x.py
x.py
/private/tmp/x.py

$ python3.9 x.py
/private/tmp/y.py
/private/tmp/y.py
/private/tmp/x.py
/private/tmp/x.py
/private/tmp/x.py
Run Code Online (Sandbox Code Playgroud)

来源: https ://docs.python.org/3/whatsnew/3.9.html#other-language-changes