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

时间:2012-02-14 03:52:35

标签: 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__))

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

5 个答案:

答案 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)

根据documentation

  

__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