Pode parecer uma pergunta para iniciantes, mas não é. Algumas abordagens comuns não funcionam em todos os casos:
sys.argv [0]
Isso significa usar path = os.path.abspath(os.path.dirname(sys.argv[0]))
, mas isso não funciona se você estiver executando em outro script Python em outro diretório, e isso pode acontecer na vida real.
__Arquivo__
Isso significa usar path = os.path.abspath(os.path.dirname(__file__))
, mas descobri que isso não funciona:
py2exe
não tem um__file__
atributo, mas há uma solução alternativa- Quando você executa a partir do IDLE com
execute()
nenhum__file__
atributo - OS X 10.6 onde eu recebo
NameError: global name '__file__' is not defined
Perguntas relacionadas com respostas incompletas:
- Python - Encontre o caminho para o arquivo sendo executado
- O caminho para o arquivo atual depende de como eu executo o programa
- Como saber o caminho do script em execução no Python?
- Mude o diretório para o diretório de um script Python
Estou procurando uma solução genérica , que funcionaria em todos os casos de uso acima.
Atualizar
Aqui está o resultado de um testcase:
Saída de python a.py (no Windows)
a.py: __file__= a.py
a.py: os.getcwd()= C:\zzz
b.py: sys.argv[0]= a.py
b.py: __file__= a.py
b.py: os.getcwd()= C:\zzz
a.py
#! /usr/bin/env python
import os, sys
print "a.py: sys.argv[0]=", sys.argv[0]
print "a.py: __file__=", __file__
print "a.py: os.getcwd()=", os.getcwd()
print
execfile("subdir/b.py")
subdir / b.py
#! /usr/bin/env python
import os, sys
print "b.py: sys.argv[0]=", sys.argv[0]
print "b.py: __file__=", __file__
print "b.py: os.getcwd()=", os.getcwd()
print
árvore
C:.
| a.py
\---subdir
b.py
NameError: global name '__file__' is not defined
uso o arquivo e isso não está dentro do IDLE. Pense que isso__file__
é definido apenas dentro dos módulos.__file__
não tinha nada a ver com Unicode. Não sei por que__file__
não está definido, mas estou procurando uma solução genérica que funcione em todos os casos.some_path/module_locator.py
?Primeiro, você precisa importar de
inspect
eos
Em seguida, onde você quiser encontrar o arquivo de origem, basta usar
fonte
NameError: global name '__file__' is not defined
(outra solução causou isso).lambda:_
. Funcionou para mim - não tenho certeza de que sempre funcionará.lambda:0
provavelmente corre mais rápido em uma quantidade incomensuravelmente pequena (ou talvez não tão pequena ... pode ser uma carga imediata ou algo ainda mais rápido para0
uma carga global_
?) Debutável se é mais limpo ou mais fácil de ler ou ainda mais inteligente / obscuro.getsourcefile(lambda:0)
terá sentido e retornaráNone
se você tentar executá-lo em um prompt interativo (jálambda
que não estará em nenhum arquivo de origem.) Se você quiser saber de onde outra função ou objeto é proveniente de um ambiente interativo, talvezabspath(getsourcefile(thatFunctionOrObject))
seja mais útil para você?essa solução é robusta mesmo em executáveis
fonte
entry_point: console_script
, mas nenhuma das outras respostas.Eu estava com um problema semelhante e acho que isso pode resolver o problema:
Funciona para scripts regulares e inativos. Tudo o que posso dizer é experimentá-lo para os outros!
Meu uso típico:
Agora eu uso __modpath__ em vez de __file__.
fonte
__modpath__
deve ser renomeado. Você provavelmente também não precisa daglobal
declaração. Caso contrário, +1!module_path()
. ou seja,module_path(lambda _: None)
que não depende de outros conteúdo do script é no.lambda _: None
e a usei por quase dois anos, mas agora descobri que podia condensá-la apenaslambda:0
. Existe alguma razão específica para sugerir o formulário que você fez, com um argumento ignorado_
, em vez de sem nenhum argumento? Existe algo superior noNone
prefixo com um espaço do que apenas0
? Ambos são igualmente enigmáticos, acho, apenas um com 8 caracteres e o outro com 14 caracteres.lambda _:
é uma função que recebe um argumento elambda:
que não aceita nenhum. Não importa, pois a função nunca é chamada. Da mesma forma, não importa qual valor de retorno é usado. Acho que escolhiNone
porque, na época, parecia indicar que era uma função do tipo "não faça nada, que nunca será chamada". O espaço à sua frente é opcional e, novamente, existe apenas para melhorar a legibilidade (sempre tentar seguir o PEP8 é um hábito).lambda
, porém, usá-lo para algo que nunca foi feito. Se você seguisse o PEP8, acho que o conteúdo certo seriapass
, nãoNone
, mas não é válido colocar uma declaração em alambda
, então você deve colocar algo com um valor. Há algumas coisas válidas 2 de caracteres que você poderia colocar em, mas eu acho que a única válidos único caractere coisas que você pode colocar em são 0-9 (ou um único nome de variável de caráter atribuído fora dolambda
.) Eu acho que0
melhor indica o nada de 0- 9A resposta curta é que não há maneira garantida de obter as informações desejadas , no entanto, existem heurísticas que funcionam quase sempre na prática. Você pode ver Como encontro a localização do executável em C? . Ele discute o problema do ponto de vista C, mas as soluções propostas são facilmente transcritas para o Python.
fonte
Consulte minha resposta para a pergunta Importando módulos da pasta pai para obter informações relacionadas, incluindo por que minha resposta não usa a
__file__
variável não confiável . Essa solução simples deve ser compatível com diferentes sistemas operacionais como módulosos
einspect
fazer parte do Python.Primeiro, você precisa importar partes dos módulos inspecionar e os .
Em seguida, use a seguinte linha em qualquer outro local necessário no seu código Python:
Como funciona:
Do módulo interno
os
(descrição abaixo), aabspath
ferramenta é importada.Em seguida
getsourcefile
(descrição abaixo) é importada do módulo internoinspect
.abspath(path)
retorna a versão absoluta / completa de um caminho de arquivogetsourcefile(lambda:0)
de alguma maneira obtém o arquivo de origem interno do objeto da função lambda, então retorna'<pyshell#nn>'
no shell do Python ou retorna o caminho do arquivo do código Python atualmente sendo executado.A utilização
abspath
do resultado degetsourcefile(lambda:0)
deve garantir que o caminho do arquivo gerado seja o caminho completo do arquivo Python.Esta solução explicada foi originalmente baseada no código da resposta em Como obtenho o caminho do arquivo executado atualmente no Python? .
fonte
Você simplesmente chamou:
ao invés de:
abspath()
fornece o caminho absoluto desys.argv[0]
(o nome do arquivo em que seu código está) edirname()
retorna o caminho do diretório sem o nome do arquivo.fonte
Isso deve funcionar de uma maneira multiplataforma (desde que você não esteja usando o intérprete ou algo assim):
sys.path[0]
é o diretório em que o script de chamada está (o primeiro lugar em que ele procura módulos a serem usados por esse script). Podemos tirar o nome do arquivo em si (no final,sys.argv[0]
fiz o que fizos.path.basename
).os.path.join
apenas os junta de uma maneira multiplataforma.os.path.realpath
apenas garante que, se obtivermos links simbólicos com nomes diferentes do script em si, ainda assim obtemos o nome real do script.Eu não tenho um Mac; então, eu não testei isso em um. Por favor, deixe-me saber se funciona, como parece que deveria. Eu testei isso no Linux (Xubuntu) com Python 3.4. Observe que muitas soluções para esse problema não funcionam em Macs (já que ouvi dizer que
__file__
não está presente em Macs).Observe que, se seu script for um link simbólico, ele fornecerá o caminho do arquivo ao qual ele vincula (e não o caminho do link simbólico).
fonte
Você pode usar
Path
nopathlib
módulo:Você pode usar call
parent
para ir mais longe no caminho:fonte
__file__
variável que pode não ser confiável (nem sempre é o caminho completo do arquivo, não funciona em todos os sistemas operacionais etc.), como os usuários do StackOverflow mencionaram frequentemente. Alterar a resposta para não incluí-la causará menos problemas e será mais compatível. Para obter mais informações, consulte stackoverflow.com/a/33532002/3787376 .Se o código vier de um arquivo, você poderá obter o nome completo
Você também pode recuperar o nome da função como
f_code.co_name
fonte
Basta adicionar o seguinte:
Ou:
fonte
Minha solução é:
fonte
fonte
'__file__'
não deve ser uma string; segundo, se você o fizer__file__
, isso funcionaria apenas para o arquivo em que esta linha de código está, e não para o arquivo que é executado?