Respostas:
Você pode usar __file__
para obter o nome do arquivo atual. Quando usado no módulo principal, este é o nome do script que foi originalmente chamado.
Se você deseja omitir a parte do diretório (que pode estar presente), você pode usar os.path.basename(__file__)
.
__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
e import os.path
são completamente equivalentes.
import sys
print sys.argv[0]
Isso será impresso foo.py
para python foo.py
, dir/foo.py
para python dir/foo.py
etc. É o primeiro argumento para python
. (Observe que após o py2exe seria foo.exe
.)
python linkfile.py
, onde linkfile.py
está 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')
.
__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 :
__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 -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çã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-c
opçã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 .
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.
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(...))
.
A partir do Python 3.4 em diante, de acordo com o PEP 428 , a PurePath
classe do pathlib
módulo também pode ser usada em qualquer um dos itens acima. Especificamente, pathlib.PurePath(...).name
extrai o nome real do arquivo e pathlib.PurePath(...).stem
extrai o nome real do arquivo sem seu sufixo.
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.
rPython
pacote do R
idioma. Esse deve ser um caso excepcional e difícil de lidar.
__main__
internamente, para uso na passagem de variáveis entre R
e 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.
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])
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.
from pathlib import Path
primeiro.
pathlib
foi introduzido no Python 3.4, portanto deve funcionar a partir do Python 3.4.
Supondo que o nome do arquivo seja foo.py
, o trecho abaixo
import sys
print sys.argv[0][:-3]
ou
import sys
print sys.argv[0][::-1][3:][::-1]
Quanto a outras extensões com mais caracteres, por exemplo, o nome do arquivo foo.pypy
import sys
print sys.argv[0].split('.')[0]
Se você deseja extrair de um caminho absoluto
import sys
print sys.argv[0].split('/')[-1].split('.')[0]
irá produzir foo
O primeiro argumento em sys será o nome do arquivo atual, portanto, isso funcionará
import sys
print sys.argv[0] # will print the file name
Se você estiver fazendo uma importação incomum (por exemplo, é um arquivo de opções), tente:
import inspect
print (inspect.getfile(inspect.currentframe()))
Observe que isso retornará o caminho absoluto para o arquivo.
podemos tentar isso para obter o nome do script atual sem extensão.
import os
script_name = os.path.splitext(os.path.basename(__file__))[0]
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"
Minha solução rápida e suja:
__file__.split('/')[-1:][0]
os.path
de nomes de arquivos de divisão
os.path.abspath(__file__)
lhe dará um caminho absoluto ( relpath()
disponível também).
sys.argv[-1]
lhe dará um caminho relativo.
No Python 3.5, você pode simplesmente fazer:
from pathlib import Path
Path(__file__).stem
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:
from pathlib import Path
print(Path(__file__).stem)
print(__file__)
executando estas saídas:
>>> python3.6 test.py
test
test.py
Exception NameError: NameError("global name '__file__' is not defined",)
"