Come correggere l'errore "ImportError: Nessun modulo denominato ..." in Python?


115

Qual è il modo corretto per correggere questo errore ImportError?

Ho la seguente struttura di directory:

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

E io sono nella directory

/home/bodacydo/work/project

Ora se digito

python ./programs/my_python_program.py

Ottengo immediatamente

ImportError: No module named foo.tasks

Il ./programs/my_python_program.pycontiene la seguente riga:

from foo.tasks import my_function

Non riesco a capire perché Python non troverà ./foo/tasks.py : è lì.

Se lo faccio dalla shell Python, allora funziona:

python
>>> from foo.tasks import my_function

Non funziona solo se lo chiamo tramite python ./programs/my_python_program.pyscript.

Risposte:


121

Python non aggiunge la directory corrente sys.path, ma piuttosto la directory in cui si trova lo script. Aggiungi /home/bodacydo/work/projecta sys.patho $PYTHONPATH.


9
Allora che senso ha avere init .py nella cartella principale? Sembra non servire a nulla se modifichi sys.path o pythonpath.

11
@Editor: __init__.pyindica solo che la directory deve essere trattata come un pacchetto, quando il suo genitore si trova sys.patho è esso stesso un pacchetto.
Ignacio Vazquez-Abrams

3
Inoltre controlla i permessi sulla cartella. Questo era il problema nel mio caso.
SidJ

15
Per aggiungere la export PYTHONPATH=`pwd`
directory

1
Quello che ha funzionato per me è stato aggiungere a $ PYTHONPATH la directory principale del progetto, nel tuo caso sarà: /home/bodacydo/work... vedi questa risposta
maledr53

33

Hai un file chiamato __init__.pynella directory foo? In caso contrario, python non riconoscerà foo come un pacchetto python.

Vedi la sezione sui pacchetti nel tutorial di python per maggiori informazioni.


Grazie e sì, l'ho avuto __init__.py. Il problema questa volta era con $PYTHONPATH. La soluzione di Ignacio ha funzionato.
bodacydo

1
I file init .py sono necessari per fare in modo che Python tratti le directory come se contenessero pacchetti; ciò viene fatto per evitare che directory con un nome comune, come stringa, nascondano involontariamente moduli validi che si verificano successivamente nel percorso di ricerca del modulo. Nel caso più semplice, init .py può essere solo un file vuoto
panofish

Grazie per avermi salvato qualche volta.
cpu_meltdown

9

Ecco una soluzione passo passo:

  1. Aggiungere uno script chiamato run.pyin /home/bodacydo/work/projecte modificare in questo modo:

    import programs.my_python_program
    programs.my_python_program.main()

    (sostituisci main()con il tuo metodo equivalente in my_python_program.)

  2. Vai a /home/bodacydo/work/project
  3. Correre run.py

Spiegazione: poiché python aggiunge a PYTHONPATH il percorso dello script da cui viene eseguito , l'esecuzione run.pyverrà aggiunta /home/bodacydo/work/project. E voilà , import foo.taskssarà trovato.


8

Soluzione di esempio per aggiungere la libreria al tuo PYTHONPATH.

  1. Aggiungi la seguente riga nel tuo ~ / .bashrc o eseguilo direttamente:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. Quindi collega la tua libreria richiesta nella tua cartella ~ / .python, ad es

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

6

Una soluzione migliore rispetto all'impostazionePYTHONPATH è usarepython -m module.path

Questo verrà impostato correttamente sys.path[0] ed è un modo più affidabile per eseguire i moduli.

Ho un breve articolo su questo problema, poiché altri rispondenti hanno menzionato il motivo per cui è python path/to/file.pyinserito path/toall'inizio di PYTHONPATH( sys.path).


2

Nella mia mente devo considerare che la foocartella è una libreria autonoma. Potrei prendere in considerazione l'idea di spostarlo nella Lib\site-packagescartella all'interno di un'installazione di Python. Potrei prendere in considerazione l'aggiunta di un foo.pthfile lì.

So che è una libreria poiché ./programs/my_python_program.pycontiene la seguente riga:

from foo.tasks import my_function

Quindi non importa che ./programssia una cartella di pari livello in ./foo. È il fatto che my_python_program.pyviene eseguito come uno script come questo:

python ./programs/my_python_program.py


0

Se hai questo problema quando usi una versione installata, quando usi setup.py, assicurati che il tuo modulo sia incluso all'internopackages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.