o que a variável __file__ significa / faz?

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

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

C = os.path.abspath(os.path.dirname(__file__))

Normalmente, eu apenas os conto com o caminho real. Mas há uma razão para essas instruções que determinam o caminho no tempo de execução, e eu realmente gostaria de entender o módulo os.path para que eu possa começar a usá-lo.

depleção
fonte

Respostas:

162

Quando um módulo é carregado de um arquivo em Python, __file__é definido como seu caminho. Você pode usá-lo com outras funções para encontrar o diretório em que o arquivo está localizado.

Tomando seus exemplos um de cada vez:

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.

Você pode ver os vários valores retornados destes aqui:

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__)))

e certifique-se de executá-lo a partir de locais diferentes (como ./text.py, ~/python/text.pye assim por diante) para ver o que diferença que faz.

paxdiablo
fonte
7
Boa resposta, mas veja outros detalhes importantes de outras respostas: __file__NÃO é definido em todos os casos, por exemplo, módulos C vinculados estaticamente. Não podemos contar com a __file__disponibilidade sempre.
18714 Chris Chris
5
No intérprete, todos os exemplos retornam name '__file__' is not defined.
user1063287
10
@ user1063287 Veja a resposta do DemoUser; __file__é o nome do caminho do arquivo do qual o módulo foi carregado, se foi carregado de um arquivo. Este meio __file__só irá funcionar quando você executá-lo como um script não em intérprete (a menos que você importá-lo no intérprete ...).
YOUNG
59

Eu só quero resolver alguma confusão primeiro. __file__não é um curinga, é um atributo. Os atributos e métodos de sublinhado duplo são considerados "especiais" por convenção e servem a um propósito especial.

http://docs.python.org/reference/datamodel.html mostra muitos dos métodos e atributos especiais, se não todos.

Nesse caso, __file__é um atributo de um módulo (um objeto de módulo). No Python, um .pyarquivo é um módulo. Então import amodule, terá um atributo __file__que significa coisas diferentes em circunstâncias diferentes.

Retirado dos documentos:

__file__é o nome do caminho do arquivo do qual o módulo foi carregado, se foi carregado de um arquivo. O __file__atributo não está presente para os módulos C que estão estaticamente vinculados ao intérprete; para módulos de extensão carregados dinamicamente de uma biblioteca compartilhada, é o nome do caminho do arquivo da biblioteca compartilhada.

No seu caso, o módulo está acessando seu próprio __file__atributo no espaço para nome global.

Para ver isso em ação, tente:

# file: test.py

print globals()
print __file__

E corra:

python test.py

{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__file__':
 'test_print__file__.py', '__doc__': None, '__package__': None}
test_print__file__.py
Derek Litz
fonte
23

De acordo com a documentação :

__file__é o nome do caminho do arquivo do qual o módulo foi carregado, se foi carregado de um arquivo. O __file__atributo não está presente para os módulos C que estão estaticamente vinculados ao intérprete; para módulos de extensão carregados dinamicamente de uma biblioteca compartilhada, é o nome do caminho do arquivo da biblioteca compartilhada.

e também :

__file__deve ser o "caminho" para o arquivo, a menos que o módulo esteja embutido (e, portanto, listado sys.builtin_module_names), caso em que o atributo não está definido.

Sudhir Bastakoti
fonte
13

O uso __file__combinado com vários os.pathmódulos permite que todos os caminhos sejam relativos ao local do diretório atual do módulo. Isso permite que seus módulos / projetos sejam portáteis para outras máquinas.

No seu projeto, você faz:

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

e tente implantá-lo no seu servidor com um diretório de implantações, para que /home/web/mydevproject/seu código não encontre os caminhos corretamente.

Sam Dolan
fonte