Tenho scripts chamando outros arquivos de script, mas preciso obter o caminho do arquivo atualmente em execução no processo.
Por exemplo, digamos que eu tenho três arquivos. Usando execfile :
script_1.py
chamadasscript_2.py
.- Por sua vez,
script_2.py
chamascript_3.py
.
Como posso obter o nome do arquivo e o caminho de script_3.py
, a partir do código dentroscript_3.py
, sem ter que passar essa informação como argumentos a partir de script_2.py
?
(Executando os.getcwd()
retorna o caminho do arquivo do script inicial original e não o arquivo atual.)
__file__
absoluto ou relativo?Respostas:
p1.py:
p2.py:
fonte
inspect.getabsfile()
e funcionou para todos os casos que tentei.os.path.realpath(__file__)
como outros já disseram. Você também pode usar o os.path.realpath para eliminar links simbólicos:
fonte
__file__
retorna 'script_name.py' e outras vezes 'script_name.pyc'. Portanto, a saída não é estável."__file__"
entre aspas (como string), fornece o diretório a partir do qual o cmd é executado, mas__file__
(sem aspas indica o caminho para o arquivo de origem ... por que é isso?os.path.realpath
função supõe que seja adir
parte do caminho.os.path.dirname(os.path.realpath(__file__))
retorna o diretório com o arquivoos.path.dirname(os.path.realpath("__file__"))
retorna cwd.os.path.dirname(os.path.realpath("here_be_dragons"))
também retorna cwd.Atualização 2018-11-28:
Aqui está um resumo dos experimentos com Python 2 e 3. Com
main.py - executa foo.py
foo.py - executa lib / bar.py
lib / bar.py - imprime expressões de caminho de arquivo
Para o Python 2, pode ser mais claro alternar para pacotes para que possa ser usado
from lib import bar
- basta adicionar__init__.py
arquivos às duas pastas.Para o Python 3,
execfile
não existe - a alternativa mais próxima éexec(open(<filename>).read())
, embora isso afete os quadros da pilha. É mais simples de usarimport foo
eimport lib.bar
- não é__init__.py
necessário arquivo.Veja também Diferença entre importação e execfile
Resposta original:
Aqui está um experimento baseado nas respostas neste tópico - com o Python 2.7.10 no Windows.
Os baseados em pilha são os únicos que parecem fornecer resultados confiáveis. Os dois últimos têm a sintaxe mais curta , ou seja -
Aqui está a estes sendo adicionados ao sys como funções! Crédito para @Usagi e @pablog
Com base nos três arquivos a seguir, e executando o main.py a partir de sua pasta com
python main.py
(também tentou execfiles com caminhos absolutos e chamando de uma pasta separada).C: \ filepaths \ main.py:
execfile('foo.py')
C: \ filepaths \ foo.py:
execfile('lib/bar.py')
C: \ filepaths \ lib \ bar.py:
fonte
Eu acho que isso é mais limpo:
e obtém as mesmas informações de:
Onde [0] é o quadro atual na pilha (parte superior da pilha) e [1] é o nome do arquivo, aumente para retroceder na pilha, ou seja,
seria o nome do arquivo do script que chamou o quadro atual. Além disso, usar [-1] o levará ao final da pilha, o script de chamada original.
fonte
inspect.getfile()
retorna o__file__
atributo se passou um objeto de módulo.inspect.currentframe()
retorna o módulo. Portanto, essa é uma maneira cara de dizer__file__
.inspect.stack()
é uma função bastante cara, mais do que justainspect.currentframe()
, e também chamainspect.getfile()
um objeto de módulo.fonte
__file__
.os.path.dirname
você fornecerá o caminho relativo de onde você está executando o script. por exemplo,python ../../test.py
oos.path.dirname
será../../
, e não o caminho absoluto para o script. Eu estava procurando abspath, mas removendo o nome do script. O primeiro elemento do sys.path aparentemente é a respostasys.path[0]
.As sugestões marcadas como melhores serão verdadeiras se o seu script consistir em apenas um arquivo.
Se você deseja descobrir o nome do executável (ou seja, o arquivo raiz passado ao intérprete python para o programa atual) de um arquivo que pode ser importado como um módulo, é necessário fazer isso (vamos supor que isso esteja em um arquivo chamado foo.py ):
import inspect
print inspect.stack()[-1][1]
Porque a última coisa (
[-1]
) na pilha é a primeira coisa que entra nela (pilhas são estruturas de dados LIFO / FILO).Em seguida, no arquivo bar.py, se você
import foo
imprimir bar.py , em vez de foo.py , que seria o valor de todos eles:__file__
inspect.getfile(inspect.currentframe())
inspect.stack()[0][1]
fonte
sys.modules['__main__'].__file__
, na verdade.isso nos dará apenas o nome do arquivo. ou seja, se abspath do arquivo for c: \ abcd \ abc.py, a segunda linha imprimirá abc.py
fonte
Não está totalmente claro o que você quer dizer com "o caminho do arquivo que está em execução no processo".
sys.argv[0]
geralmente contém a localização do script que foi chamado pelo intérprete Python. Verifique a documentação do sistema para mais detalhes.Como o @Tim e o @Pat Notz apontaram, o atributo __file__ fornece acesso a
fonte
Eu tenho um script que deve funcionar no ambiente Windows. Este código cortado é o que eu terminei:
é uma decisão bastante hacky. Mas não requer bibliotecas externas e é a coisa mais importante no meu caso.
fonte
Tente isso,
fonte
Não há necessidade de inspecionar ou qualquer outra biblioteca.
Isso funcionou para mim quando tive que importar um script (de um diretório diferente do script executado), que usava um arquivo de configuração que residia na mesma pasta que o script importado.
fonte
O
__file__
atributo funciona para o arquivo que contém o código de execução principal e para os módulos importados.Consulte https://web.archive.org/web/20090918095828/http://pyref.infogami.com/__file__
fonte
isso imprimiria o caminho do script atualmente em execução
fonte
Acho que
__file__
parece que você também pode querer conferir o módulo de inspeção .fonte
Você pode usar
inspect.stack()
fonte
Como o Python 3 é bastante popular, eu queria incluir uma
pathlib
resposta, pois acredito que agora é provavelmente uma ferramenta melhor para acessar informações de arquivos e caminhos.Se você está procurando o diretório do arquivo atual, é tão fácil quanto adicionar
.parent
àPath()
instrução:fonte
fonte
Isso deve funcionar:
fonte
fonte
Para obter o diretório do script em execução
fonte
Eu sempre usei o recurso OS do Current Working Directory, ou CWD. Isso faz parte da biblioteca padrão e é muito fácil de implementar. Aqui está um exemplo:
fonte
python script.py
comando na mesma pasta que você já é, quando na realidade é o mesmo que executarpwd
no linux.Eu usei a abordagem com __file__,
os.path.abspath(__file__)
mas há um pequeno truque, ele retorna o arquivo .py quando o código é executado pela primeira vez, as próximas execuções dão o nome do arquivo * .pyc,
então fiquei com:
inspect.getfile(inspect.currentframe())
ou
sys._getframe().f_code.co_filename
fonte
Eu escrevi uma função que leva em conta o depurador do eclipse e o mais unittest . Ele retorna a pasta do primeiro script que você inicia. Opcionalmente, você pode especificar o __file__ var, mas o principal é que você não precisa compartilhar essa variável em toda a sua hierarquia de chamadas .
Talvez você possa lidar com outros casos específicos da pilha que eu não vi, mas para mim está tudo bem.
fonte
Para manter a consistência da migração entre plataformas (macOS / Windows / Linux), tente:
path = r'%s' % os.getcwd().replace('\\','/')
fonte
A maneira mais simples é:
em script_1.py:
em script_2.py:
PS: Eu tentei
execfile
, mas como ele lê script_2.py como uma string,sys.argv[0]
retornou<string>
.fonte
Aqui está o que eu uso para que eu possa lançar meu código em qualquer lugar sem problemas.
__name__
está sempre definido, mas__file__
só é definido quando o código é executado como um arquivo (por exemplo, não no IDLE / iPython).Como alternativa, isso pode ser escrito como:
fonte
A maioria dessas respostas foi escrita no Python versão 2.x ou anterior. No Python 3.x, a sintaxe da função print foi alterada para exigir parênteses, ou seja, print ().
Portanto, essa resposta mais alta do usuário13993 no Python 2.x:
Torna-se no Python 3.x:
fonte
se você quiser apenas o nome do arquivo sem
./
ou.py
você pode tentar issofile_name
imprimirá o test-script, você poderá gerar o que quiser, alterando o índice dentro de []fonte
fonte