2012-02-14 61 views
56
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模块,所以我可以开始使用它。__file__变量意味着什么?

+5

很显然,这不是一个通配符。 – tripleee 2012-02-14 04:59:51

+3

它是一个“魔术”变量;通配符意味着完全不同的东西。 – 2012-02-14 05:47:03

回答

66

当在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等)运行地看到,能起到什么作用。

+3

很好的答案,但请参阅其他答案的其他重要细节:'__file__'并未在所有情况下定义,例如静态链接的C模块。我们不能指望'__file__'始终可用。 – 2014-02-18 15:46:56

+2

在解释器中,所有示例都返回'name'__file__'未定义。 – user1063287 2014-11-25 22:51:09

+2

@ user1063287看DemoUser的答案; '__file__'是从模块加载的文件的路径名,如果它是从文件加载的。这意味着'__file__'只有在你作为脚本不在解释器中运行时才会起作用(除非你在解释器中导入它) – YOUNG 2015-07-14 00:48:18

10

documentation

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

also和:

__file__是成为“路径”在这种情况下,属性未设置,除非该模块被内置(并因此列入sys.builtin_module_names)该文件。

8

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

在你的项目你做:

A = '/Users/myname/Projects/mydevproject/somefile.txt' 

,然后尝试将其与像/home/web/mydevproject/一个部署目录部署到服务器,然后你的代码将无法正确找到路径。

30

我只想先解决一些困惑。 __file__不是通配符,它​​是一个属性。双下划线的属性和方法被认为是“特殊”的约定和服务于特殊目的。

http://docs.python.org/reference/datamodel.html显示了许多特殊的方法和属性,如果不是全部的话。

在这种情况下,__file__是模块(模块对象)的属性。在Python中,.py文件是一个模块。因此import amodule将具有__file__的属性,这意味着在不同情况下的不同事情。

从文档摘自:

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

在你的情况下,模块正在全局命名空间中访问它自己的__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