Python 3.2: " Exception NameError: NameError("global name '__file__' is not defined",)"
sdaau
20
@sdaau: __file__não está definido no intérprete interativo, porque não faz sentido lá. Ele é definido pela implementação de importação; portanto, se você usar um mecanismo de importação não padrão, ele também poderá ser desabilitado.
Sven Marnach
8
Pelo menos para o Python 2.7, acredito que import osseja necessário que isso funcione. Eu adicionaria isso na resposta.
Nick Chammas
14
@ cdunn2001: import ose import os.pathsão completamente equivalentes.
Sven Marnach
2
@ Sven-Marnach: Oh, você está certo . Eu venho fazendo errado há anos!
cdunn2001
136
import sys
print sys.argv[0]
Isso será impresso foo.pypara python foo.py, dir/foo.pypara python dir/foo.pyetc. É o primeiro argumento para python. (Observe que após o py2exe seria foo.exe.)
@ DenisMalinovsky: defina "não funcionará". Se você ligar python linkfile.py, onde linkfile.pyestá um link simbólico para realfile.py, sys.argv[0]será 'linkfile.py', que pode ou não ser o que você deseja; é certamente o que eu espero . __file__é o mesmo: será linkfile.py. Se você quiser encontrar 'realfile.py'a partir 'linkfile.py', tente os.path.realpath('linkfile.py').
13133 Chris Morgan
6
+1 porque é (a) um pouco mais organizado e (b) ainda funcionará no módulo (onde a variável file seria o arquivo do módulo, não o executado).
21915 Robert
Essa resposta é boa porque também funciona no IDLE. Como uma nota, para obter apenas o nome do arquivo, você pode escrever os.path.basename (sys.argv [0])
Steven Bluen
Mais importante, isso não funciona, exceto de dentro do arquivo principal. Não use isso, use em __file__vez disso.
Apollys suporta Monica
O QUE!!! Você tentou isso? Exatamente o oposto é verdadeiro. O interlocutor perguntou o nome do script python que está sendo executado - não o arquivo python que está em execução no momento. Imagine que você tenha um script que, quando ocorrer um erro, imprima o nome do script junto com os argumentos permitidos. Você coloca isso em uma função, usando uma dessas 2 técnicas. Em algum momento, você decide mover a função para uma biblioteca externa. Deseja imprimir o nome do script principal em execução ou o nome do arquivo da biblioteca que está sendo executado?
John Deighan 30/04
71
Por uma questão de integridade, pensei que valeria a pena resumir os vários resultados possíveis e fornecer referências para o comportamento exato de cada um:
__file__é o arquivo em execução no momento, conforme detalhado na documentação oficial :
__file__é o nome do caminho do arquivo do qual o módulo foi carregado, se foi carregado de um arquivo. O __file__atributo pode estar ausente para certos tipos de módulos, como 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.
A partir do Python3.4 em diante, pela edição 18416 , __file__sempre é um caminho absoluto, a menos que o arquivo em execução no momento seja um script que tenha sido executado diretamente (não através do interpretador com a -mopção de linha de comando) usando um caminho relativo.
__main__.__file__(requer importação __main__) simplesmente acessa o __file__atributo acima mencionado do módulo principal , por exemplo, do script que foi chamado a partir da linha de comando.
sys.argv[0](requer importação sys) é o nome do script que foi chamado a partir da linha de comando e pode ser um caminho absoluto, conforme detalhado na documentação oficial :
argv[0]é o nome do script (depende do sistema operacional se este é um nome de caminho completo ou não). Se o comando foi executado usando a -copção de linha de comando para o intérprete, argv[0]é definido como a sequência '-c'. Se nenhum nome de script foi passado para o interpretador Python, argv[0]é a string vazia.
Como mencionado em outra resposta a essa pergunta , os scripts Python que foram convertidos em programas executáveis independentes por meio de ferramentas como py2exe ou PyInstaller podem não exibir o resultado desejado ao usar essa abordagem (ou seja sys.argv[0], manter o nome do executável em vez do nome do arquivo Python principal nesse executável).
Se nenhuma das opções mencionadas acima parecer funcionar, provavelmente devido a uma operação de importação irregular, o módulo de inspeção poderá ser útil. Em particular, a invocação inspect.getfile(...)de inspect.currentframe()poderia funcionar, embora o último retornasseNone ao executar em uma implementação sem o quadro de pilha Python .
Manipulando Links Simbólicos
Se o script atual for um link simbólico, todas as opções acima retornariam o caminho do link simbólico em vez do caminho do arquivo real e os.path.realpath(...)devem ser invocadas para extrair o último.
Manipulações adicionais que extraem o nome do arquivo real
os.path.basename(...)pode ser chamado em qualquer uma das opções acima para extrair o nome do arquivo real e os.path.splitext(...)pode ser chamado no nome do arquivo real para truncar seu sufixo, como em os.path.splitext(os.path.basename(...)).
Observe que __file__fornecerá o arquivo em que esse código reside, que pode ser importado e diferente do arquivo principal que está sendo interpretado. Para obter o arquivo principal, o módulo __main__ especial pode ser usado:
import __main__ as main
print(main.__file__)
Observe que __main__.__file__funciona no Python 2.7, mas não no 3.2, portanto, use a sintaxe de importação como acima para torná-lo portátil.
Isso funciona em muitos casos, mas não quando estou usando o rPythonpacote do Ridioma. Esse deve ser um caso excepcional e difícil de lidar.
Leonid
De fato, o pacote rPython incorpora o interpretador python, o que significa que não há um arquivo 'principal' como existe quando o python está rodando por conta própria (você encontrará o mesmo comportamento sempre que o python for incorporado). Ele é importado __main__internamente, para uso na passagem de variáveis entre Re python, portanto, seria relativamente fácil configurá-lo __main__.__file__antes de chamar qualquer outra coisa, mas não tenho certeza do que seria um valor apropriado nesse caso.
Perkins
42
As respostas acima são boas. Mas achei esse método mais eficiente usando os resultados acima.
Isso resulta no nome do arquivo de script real, não em um caminho.
import sys
import os
file_name = os.path.basename(sys.argv[0])
Eu gosto de separar a extensão também, então eu uso: os.path.splitext (os.path.basename (sys.argv [0])) [0]
RufusVS
19
Para versões modernas do Python (3.4+), Path(__file__).namedeve ser mais idiomático. Além disso, Path(__file__).stemfornece o nome do script sem a .pyextensão.
todas essas respostas são ótimas, mas têm alguns problemas Você pode não ver à primeira vista.
vamos definir o que queremos - queremos o nome do script que foi executado, não o nome do módulo atual - portanto __file__, só funcionará se for usado no script executado, não em um módulo importado.
sys.argvtambém é questionável - e se o seu programa foi chamado pelo pytest? ou corredor pydoc? ou se foi chamado por uwsgi?
e - existe um terceiro método para obter o nome do script, que eu não vi nas respostas - Você pode inspecionar a pilha.
Outro problema é que você (ou algum outro programa) pode mexer com sys.argve__main__.__file__ - pode estar presente, pode não estar. Pode ser válido ou não. Pelo menos Você pode verificar se o script (o resultado desejado) existe!
minha biblioteca bitranox / lib_programname no github faz exatamente isso:
existe pytest, docrunner, etc no sys.argv? -> se sim, ignore isso
podemos obter um resultado válido aqui?
caso contrário: inspecione a pilha e obtenha o resultado daí, possivelmente
se também a pilha não der um resultado válido, lance uma exceção.
por esse caminho, a minha solução está trabalhando até agora com setup.py test, uwsgi, pytest, pycharm pytest, pycharm docrunner (doctest), dreampie,eclipse
também há um bom artigo de blog sobre esse problema de Dough Hellman, "Determinando o nome de um processo no Python"
Exception NameError: NameError("global name '__file__' is not defined",)
"__file__
não está definido no intérprete interativo, porque não faz sentido lá. Ele é definido pela implementação de importação; portanto, se você usar um mecanismo de importação não padrão, ele também poderá ser desabilitado.import os
seja necessário que isso funcione. Eu adicionaria isso na resposta.import os
eimport os.path
são completamente equivalentes.Isso será impresso
foo.py
parapython foo.py
,dir/foo.py
parapython dir/foo.py
etc. É o primeiro argumento parapython
. (Observe que após o py2exe seriafoo.exe
.)fonte
python linkfile.py
, ondelinkfile.py
está um link simbólico pararealfile.py
,sys.argv[0]
será'linkfile.py'
, que pode ou não ser o que você deseja; é certamente o que eu espero .__file__
é o mesmo: serálinkfile.py
. Se você quiser encontrar'realfile.py'
a partir'linkfile.py'
, tenteos.path.realpath('linkfile.py')
.__file__
vez disso.Por uma questão de integridade, pensei que valeria a pena resumir os vários resultados possíveis e fornecer referências para o comportamento exato de cada um:
__file__
é o arquivo em execução no momento, conforme detalhado na documentação oficial :A partir do Python3.4 em diante, pela edição 18416 ,
__file__
sempre é um caminho absoluto, a menos que o arquivo em execução no momento seja um script que tenha sido executado diretamente (não através do interpretador com a-m
opção de linha de comando) usando um caminho relativo.__main__.__file__
(requer importação__main__
) simplesmente acessa o__file__
atributo acima mencionado do módulo principal , por exemplo, do script que foi chamado a partir da linha de comando.sys.argv[0]
(requer importaçãosys
) é o nome do script que foi chamado a partir da linha de comando e pode ser um caminho absoluto, conforme detalhado na documentação oficial :Como mencionado em outra resposta a essa pergunta , os scripts Python que foram convertidos em programas executáveis independentes por meio de ferramentas como py2exe ou PyInstaller podem não exibir o resultado desejado ao usar essa abordagem (ou seja
sys.argv[0]
, manter o nome do executável em vez do nome do arquivo Python principal nesse executável).Se nenhuma das opções mencionadas acima parecer funcionar, provavelmente devido a uma operação de importação irregular, o módulo de inspeção poderá ser útil. Em particular, a invocação
inspect.getfile(...)
deinspect.currentframe()
poderia funcionar, embora o último retornasseNone
ao executar em uma implementação sem o quadro de pilha Python .Manipulando Links Simbólicos
Se o script atual for um link simbólico, todas as opções acima retornariam o caminho do link simbólico em vez do caminho do arquivo real e
os.path.realpath(...)
devem ser invocadas para extrair o último.Manipulações adicionais que extraem o nome do arquivo real
os.path.basename(...)
pode ser chamado em qualquer uma das opções acima para extrair o nome do arquivo real eos.path.splitext(...)
pode ser chamado no nome do arquivo real para truncar seu sufixo, como emos.path.splitext(os.path.basename(...))
.A partir do Python 3.4 em diante, de acordo com o PEP 428 , a
PurePath
classe dopathlib
módulo também pode ser usada em qualquer um dos itens acima. Especificamente,pathlib.PurePath(...).name
extrai o nome real do arquivo epathlib.PurePath(...).stem
extrai o nome real do arquivo sem seu sufixo.fonte
Observe que
__file__
fornecerá o arquivo em que esse código reside, que pode ser importado e diferente do arquivo principal que está sendo interpretado. Para obter o arquivo principal, o módulo __main__ especial pode ser usado:Observe que
__main__.__file__
funciona no Python 2.7, mas não no 3.2, portanto, use a sintaxe de importação como acima para torná-lo portátil.fonte
rPython
pacote doR
idioma. Esse deve ser um caso excepcional e difícil de lidar.__main__
internamente, para uso na passagem de variáveis entreR
epython
, portanto, seria relativamente fácil configurá-lo__main__.__file__
antes de chamar qualquer outra coisa, mas não tenho certeza do que seria um valor apropriado nesse caso.As respostas acima são boas. Mas achei esse método mais eficiente usando os resultados acima.
Isso resulta no nome do arquivo de script real, não em um caminho.
fonte
Para versões modernas do Python (3.4+),
Path(__file__).name
deve ser mais idiomático. Além disso,Path(__file__).stem
fornece o nome do script sem a.py
extensão.fonte
from pathlib import Path
primeiro.pathlib
foi introduzido no Python 3.4, portanto deve funcionar a partir do Python 3.4.Tente o seguinte:
fonte
Nota: Se você estiver usando o Python 3+, use a função print ()
Supondo que o nome do arquivo seja
foo.py
, o trecho abaixoou
Quanto a outras extensões com mais caracteres, por exemplo, o nome do arquivo
foo.pypy
Se você deseja extrair de um caminho absoluto
irá produzir
foo
fonte
__file__
esys.argv[0]
, ver stackoverflow.com/questions/5851588/...O primeiro argumento em sys será o nome do arquivo atual, portanto, isso funcionará
fonte
Se você estiver fazendo uma importação incomum (por exemplo, é um arquivo de opções), tente:
Observe que isso retornará o caminho absoluto para o arquivo.
fonte
podemos tentar isso para obter o nome do script atual sem extensão.
fonte
Como o OP solicitou o nome do arquivo de script atual, eu preferiria
fonte
todas essas respostas são ótimas, mas têm alguns problemas Você pode não ver à primeira vista.
vamos definir o que queremos - queremos o nome do script que foi executado, não o nome do módulo atual - portanto
__file__
, só funcionará se for usado no script executado, não em um módulo importado.sys.argv
também é questionável - e se o seu programa foi chamado pelo pytest? ou corredor pydoc? ou se foi chamado por uwsgi?e - existe um terceiro método para obter o nome do script, que eu não vi nas respostas - Você pode inspecionar a pilha.
Outro problema é que você (ou algum outro programa) pode mexer com
sys.argv
e__main__.__file__
- pode estar presente, pode não estar. Pode ser válido ou não. Pelo menos Você pode verificar se o script (o resultado desejado) existe!minha biblioteca bitranox / lib_programname no github faz exatamente isso:
__main__
está presente__main__.__file__
está presente__main__.__file__
um resultado válido (esse script existe?)por esse caminho, a minha solução está trabalhando até agora com
setup.py test
,uwsgi
,pytest
,pycharm pytest
,pycharm docrunner (doctest)
,dreampie
,eclipse
também há um bom artigo de blog sobre esse problema de Dough Hellman, "Determinando o nome de um processo no Python"
fonte
Minha solução rápida e suja:
fonte
os.path
de nomes de arquivos de divisãoos.path.abspath(__file__)
lhe dará um caminho absoluto (relpath()
disponível também).sys.argv[-1]
lhe dará um caminho relativo.fonte
No Python 3.5, você pode simplesmente fazer:
Veja mais aqui: https://docs.python.org/3.5/library/pathlib.html#pathlib.PurePath.stem
Por exemplo, eu tenho um arquivo no meu diretório de usuário chamado
test.py
com este dentro:executando estas saídas:
fonte