Como adicionar um módulo Python ao syspath?

69

Eu tenho uma estrutura de arquivos como esta:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Quero importar para foo2.py e foo1.py. Eu tentei, mas não funciona no Ubuntu:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py
user284474
fonte
Você tem um __init__.pyarquivo em sua pasta? é assim que o python cria pacotes e permite importar módulos desse pacote. guide.python-distribute.org/creation.html
Bryan
Eu tenho o arquivo init.py no Common e no TestFolder
user284474
você precisa-lo no diretório de pastas, bem como nas sub-pastas se você deseja importar
Bryan
Este init .py está vazio?
User284474
11
Sim, pode estar vazio. A menos que você precisa de uma certa configuração para o seu pacote, mas você deve estar bem com ele estar vazio
Bryan

Respostas:

115

Como o python encontra seus módulos

A rigor, um módulo é um único arquivo python, enquanto um pacote é uma pasta que contém arquivos python, acompanhados por um arquivo (pode estar vazio) nomeado __init__.py, para dizer ao python que é um pacote do qual importar módulos. Nos dois casos, os módulos precisam de sua .pyextensão, mas a importação é feita sem (veja mais abaixo).

Por padrão, o Python procura seus módulos e pacotes no $PYTHONPATH.

Para descobrir o que está incluído no $ PYTHONPATH, execute o seguinte código em python (3):

import sys
print(sys.path)

Como adicionar um diretório

Ocasionalmente

De dentro de um arquivo python, você pode adicionar caminhos ocasionalmente ao caminho padrão, adicionando as seguintes linhas na seção principal do aplicativo ou script python:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Por exemplo:

se eu tiver uma pasta: /home/myname/pythonfilese desejar importar o arquivo module_1.py, localizado nesse diretório, adicione-o à seção head do meu código:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

E eu posso simplesmente importar o arquivo module_1.py:

import module_1

Quando crio um pacote e quero importar os módulos do pacote, preciso criar uma pasta $PYTHONPATHcontendo os módulos, acompanhada de um arquivo (pode estar vazio) chamado__init__.py

Por exemplo:

Para importar a partir de um pacote (pasta) chamada my_packageem /home/myname/pythonfiles, adicione o /home/myname/pythonfilescaminho para o seu $PYTHONPATH, como no exemplo 1, e importar o módulo chamado module_2.py(dentro da pasta do pacote) simplesmente com: `

from <packagename> import module_2

Adicionando diretórios $PYTHONPATHpermanentemente:

Adicione a seguinte linha ao seu ~/.profilearquivo.

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Subdiretórios

De dentro de um pacote, os subdiretórios não são incluídos assim; você precisa "encadear" os diretórios. Para importar um módulo module_3.py, dentro da pasta subfolderdentro da pasta packagename:

import packagename.subfolder.module_3

Dado o fato de que todas as subpastas no pacote incluem seu próprio __init__.pyarquivo.

Quando um módulo está no mesmo diretório que o script ou aplicativo

Não há necessidade de inserir o caminho para um módulo quando ele estiver no mesmo diretório que o script ou aplicativo, ele será adicionado automaticamente.

Exemplo:

Se eu tiver uma pasta contendo script.pye module.py, eu posso simplesmente importar o módulo:

import module
Jacob Vlijm
fonte
Eu também gostaria de sugerir a leitura python.org/dev/peps/pep-0328 , especialmente se você está alvejando Python 3 (ou planejando para atingir no futuro)
zaadeh
Por que printenv PYTHONPATHnão é nada?
Stevie G
11
sys.path.append("/path/to/your/package_or_module")também adiciona um caminho ao padrão e é menos confuso. Em comparação com o sys.path.insert(0,...)que tem 0como primeiro argumento.
Paul Rougieux
11
@PaulRougieux: O problema com a anexação ao caminho é que o módulo já pode existir em outras partes do caminho (em um arquivo .egg por exemplo) e você vai pegar aquela versão do seu módulo em vez de um em seu arquivo.
snark
6

A maneira correta de usar a importação relativa é:

from ..Common import foo1

E você também precisa de um __init__.pyem todas as suas pastas.

Sylvain Pineau
fonte
11
Valeu. Mas se eu tiver um módulo com duas pastas, como importar isso? de .... Pasta não está funcionando
user284474
Funciona com um único nível?
Sylvain Pineau 23/05
Com um único nível, funciona.
User284474
ok, você poderia aceitar esta resposta? para multinível se você pudesse fazer uma pergunta diferente, mas primeiro dar uma olhada nesta questão e essa resposta para a melhor maneira de chamar seus módulos dentro de um pacote
Sylvain Pineau
Isso é verdade para Python 2 ou Python 3? Ou ambos?
alex
2

Nota: esta resposta está desatualizada para a versão mais recente do python 3, mas está aqui para a versão anterior. Para mais informações, leia os comentários e https://www.python.org/dev/peps/pep-0420/


Essencialmente, todas as pastas com código python que você deseja adicionar ao syspath precisam de um arquivo __init__.py. Esses arquivos __init__.py podem estar vazios.

don.joey
fonte
Pelo que entendi, esse não é mais o caso, o diretório agora se torna um "espaço para nome".
Aaron Hall
@AaronHall interessante, fonte?
don.joey
11
Tente isso por evidências: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"também aqui está alguma documentação relevante, PEP 420, que descreve a adição da semântica pacote namespace
Aaron Hall