Como corrigir o erro “ImportError: No module named…” no Python?


115

Qual é a maneira correta de corrigir esse erro ImportError?

Tenho a seguinte estrutura de diretório:

/home/bodacydo
/home/bodacydo/work
/home/bodacydo/work/project
/home/bodacydo/work/project/programs
/home/bodacydo/work/project/foo

E eu estou no diretório

/home/bodacydo/work/project

Agora se eu digitar

python ./programs/my_python_program.py

Eu imediatamente recebo

ImportError: No module named foo.tasks

O ./programs/my_python_program.pycontém a seguinte linha:

from foo.tasks import my_function

Não consigo entender por que o python não encontra ./foo/tasks.py- está lá.

Se eu fizer isso a partir do shell Python, funcionará:

python
>>> from foo.tasks import my_function

Só não funciona se eu chamar via python ./programs/my_python_program.pyscript.

Respostas:


121

Python não adiciona o diretório atual sys.path, mas sim o diretório em que o script está. Adicione /home/bodacydo/work/projecta sys.pathou $PYTHONPATH.


9
Então qual é o objetivo de ter init .py na pasta raiz? Parece não ter nenhum propósito se você editar sys.path ou pythonpath.

11
@Editor: __init__.pyapenas indica que o diretório deve ser tratado como um pacote, quando seu pai está dentro sys.pathou é um pacote.
Ignacio Vazquez-Abrams

3
Além disso, verifique as permissões da pasta. Esse foi o problema no meu caso.
SidJ

15
Para adicionar o dir atual ao caminho python, useexport PYTHONPATH=`pwd`
rodorgas

1
O que funcionou para mim foi adicionar a $ PYTHONPATH o diretório pai do projeto, no seu caso será: /home/bodacydo/work... veja esta resposta
maledr53

33

Você tem um arquivo chamado __init__.pyno diretório foo? Do contrário, o python não reconhecerá foo como um pacote python.

Consulte a seção sobre pacotes no tutorial de python para obter mais informações.


Obrigado e sim, eu tinha __init__.py. O problema desta vez era com $PYTHONPATH. A solução de Ignacio funcionou.
bodacydo

1
Os arquivos init .py são necessários para fazer o Python tratar os diretórios como contendo pacotes; isso é feito para evitar que diretórios com um nome comum, como string, ocultem inadvertidamente módulos válidos que ocorrem posteriormente no caminho de pesquisa do módulo. No caso mais simples, init .py pode ser apenas um arquivo vazio
panofish

Obrigado por me salvar algum dia.
cpu_meltdown

9

Aqui está uma solução passo a passo:

  1. Adicionar um script chamado run.pyem /home/bodacydo/work/projecte editá-lo como este:

    import programs.my_python_program
    programs.my_python_program.main()
    

    (substitua main()pelo método equivalente em my_python_program.)

  2. Vamos para /home/bodacydo/work/project
  3. Corre run.py

Explicação: Como python anexa a PYTHONPATH o caminho do script a partir do qual é executado , a execução run.pyirá anexar /home/bodacydo/work/project. E voilà , import foo.tasksserá encontrado.


8

Solução de exemplo para adicionar a biblioteca ao seu PYTHONPATH.

  1. Adicione a seguinte linha em seu ~ / .bashrc ou apenas execute-a diretamente:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. Em seguida, vincule a biblioteca necessária à pasta ~ / .python, por exemplo

    ln -s /home/user/work/project/foo ~/.python/

6

Uma solução melhor do que definir PYTHONPATHé usarpython -m module.path

Isso será definido corretamente sys.path[0]e é uma maneira mais confiável de executar módulos.

Eu tenho uma rápida redação sobre este problema, como outros respondentes mencionaram, o motivo para isso é python path/to/file.pycolocar path/tono início de PYTHONPATH( sys.path).


2

Em minha mente, devo considerar que a foopasta é uma biblioteca independente. Talvez eu queira movê-lo para a Lib\site-packagespasta dentro de uma instalação do Python. Talvez eu queira adicionar um foo.ptharquivo lá.

Eu sei que é uma biblioteca, pois ./programs/my_python_program.pycontém a seguinte linha:

from foo.tasks import my_function

Portanto, não importa que ./programsseja uma pasta irmã para ./foo. É o fato de que my_python_program.pyé executado como um script assim:

python ./programs/my_python_program.py


0

Se você tiver esse problema ao usar uma versão instalada, ao usar setup.py, certifique-se de que seu módulo está incluído dentropackages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.