Outro desenvolvedor e eu discordamos sobre se PYTHONPATH ou sys.path devem ser usados para permitir que Python encontre um pacote Python em um diretório de usuário (por exemplo, desenvolvimento).
Temos um projeto Python com uma estrutura de diretório típica:
Project
setup.py
package
__init__.py
lib.py
script.py
Em script.py, precisamos fazer import package.lib
. Quando o pacote é instalado em sites-packages, script.py pode encontrar package.lib
.
Ao trabalhar a partir de um diretório de usuário, entretanto, algo mais precisa ser feito. Minha solução é definir meu PYTHONPATH para incluir "~ / Projeto". Outro desenvolvedor deseja colocar esta linha de código no início de script.py:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
Para que Python possa encontrar a cópia local de package.lib
.
Acho que é uma má ideia, já que esta linha só é útil para desenvolvedores ou pessoas que executam uma cópia local, mas não posso dar uma boa razão para que seja uma má ideia.
Devemos usar PYTOHNPATH, sys.path ou tudo bem?
fonte
Respostas:
Se o único motivo para modificar o caminho for para desenvolvedores trabalhando em sua árvore de trabalho, você deve usar uma ferramenta de instalação para configurar seu ambiente para você. virtualenv é muito popular, e se você estiver usando ferramentas de instalação, você pode simplesmente executar
setup.py develop
para semi-instalar a árvore de trabalho em sua instalação atual do Python.fonte
Eu odeio PYTHONPATH. Acho frágil e irritante definir por usuário (especialmente para usuários de daemon) e acompanhar conforme as pastas do projeto se movem. Eu preferiria definir
sys.path
nos scripts invoke para projetos autônomos.No entanto,
sys.path.append
não é a maneira de fazer isso. Você pode obter facilmente duplicatas e não classifica os.pth
arquivos. Melhor (e mais legível):site.addsitedir
.E
script.py
normalmente não seria o lugar mais apropriado para fazer isso, pois está dentro do pacote que você deseja disponibilizar no caminho. Módulos de biblioteca certamente não devem se tocarsys.path
. Em vez disso, você normalmente teria um script hashbanged fora do pacote que você usa para instanciar e executar o aplicativo, e é nesse script de wrapper trivial que você colocaria detalhes de implantação comosys.path
-frobbing.fonte
site.addsitedir
é que ele faz umappend
onsys.path
, o que significa que um pacote instalado terá precedência sobre o pacote local em desenvolvimento (e isso pode causar uma confusão).sys.path.insert(0...
é necessário para superar isso.sys.path.insert(1
. stackoverflow.com/q/10095037/125507Em geral, eu consideraria a configuração de uma variável de ambiente (como PYTHONPATH) uma prática ruim. Embora isso possa ser bom para uma depuração isolada, usar isso como
uma prática regular pode não ser uma boa ideia.
O uso da variável de ambiente leva a situações como "funciona para mim", quando outra
pessoa relata problemas na base de código. Além disso, pode-se realizar a mesma prática com o ambiente de teste, levando a situações como a execução de testes bem para um desenvolvedor em particular, mas provavelmente falhando quando alguém os inicia.
fonte
Eu acho que, neste caso, usar PYTHONPATH é uma coisa melhor, principalmente porque ele não introduz código desnecessário (questionável).
Afinal, se você pensar bem, seu usuário não precisa disso
sys.path
, porque seu pacote será instalado em sites-packages, porque você estará usando um sistema de empacotamento.Se o usuário escolher executar a partir de uma "cópia local", como você a chama, observei que a prática usual é afirmar que o pacote precisa ser adicionado a PYTHONPATH manualmente, se usado fora dos pacotes do site .
fonte
Junto com os muitos outros motivos já mencionados, você também pode apontar que a codificação permanente
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
é frágil porque presume a localização de script.py - só funcionará se script.py estiver localizado em Projeto / pacote. Ele será interrompido se um usuário decidir mover / copiar / symlink script.py (quase) para qualquer outro lugar.
fonte
Nem hackear
PYTHONPATH
nemsys.path
é uma boa ideia pelos motivos mencionados. E para vincular o projeto atual à pasta de pacotes do site, há realmente uma maneira melhor do quepython setup.py develop
, conforme explicado aqui :pip install --editable path/to/project
Se você ainda não tem um setup.py na pasta raiz do seu projeto, este é bom o suficiente para começar:
fonte