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 osseja necessário que isso funcione. Eu adicionaria isso na resposta.
import ose import os.pathsão completamente equivalentes.
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.)
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').
__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 -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 .
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 PurePathclasse do pathlibmódulo também pode ser usada em qualquer um dos itens acima. Especificamente, pathlib.PurePath(...).nameextrai o nome real do arquivo e pathlib.PurePath(...).stemextrai 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.
rPythonpacote do Ridioma. Esse deve ser um caso excepcional e difícil de lidar.
__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.
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__).namedeve ser mais idiomático. Além disso, Path(__file__).stemfornece o nome do script sem a .pyextensão.
from pathlib import Pathprimeiro.
pathlibfoi 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.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:
__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.pathde 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.pycom 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",)"