Bagaimana cara memperbaiki kesalahan "ImportError: No module bernama ..." dengan Python?

115

Apa cara yang benar untuk memperbaiki kesalahan ImportError ini?

Saya memiliki struktur direktori berikut:

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

Dan saya ada di direktori

/home/bodacydo/work/project

Sekarang jika saya mengetik

python ./programs/my_python_program.py

Saya langsung mengerti

ImportError: No module named foo.tasks

The ./programs/my_python_program.pyberisi baris berikut:

from foo.tasks import my_function

Saya tidak mengerti mengapa python tidak akan menemukan ./foo/tasks.py- itu ada di sana.

Jika saya melakukannya dari shell Python, maka itu berhasil:

python
>>> from foo.tasks import my_function

Itu hanya tidak berfungsi jika saya menyebutnya melalui python ./programs/my_python_program.pyskrip.

bodacydo
sumber

Jawaban:

121

Python tidak menambahkan direktori saat ini sys.path, melainkan direktori tempat skrip berada. Tambahkan /home/bodacydo/work/projectke salah satu sys.pathatau $PYTHONPATH.

Ignacio Vazquez-Abrams
sumber
9
Jadi apa gunanya memiliki init .py di folder root? Tampaknya tidak ada gunanya jika Anda mengedit sys.path atau pythonpath.
11
@Editor: __init__.pyhanya menunjukkan bahwa direktori harus diperlakukan sebagai sebuah paket, jika induknya ada di dalam sys.pathatau merupakan sebuah paket.
Ignacio Vazquez-Abrams
3
Selain itu, periksa izin pada folder tersebut. Itulah masalah dalam kasus saya.
SidJ
15
Untuk menambahkan dir saat ini ke jalur python, gunakanexport PYTHONPATH=`pwd`
rodorgas
1
Apa yang berhasil bagi saya adalah menambahkan ke $ PYTHONPATH direktori induk proyek, dalam kasus Anda akan menjadi: /home/bodacydo/work... lihat jawaban ini
maledr53
33

Apakah Anda memiliki file bernama __init__.pydi direktori foo? Jika tidak maka python tidak akan mengenali foo sebagai paket python.

Lihat bagian tentang paket di tutorial python untuk informasi lebih lanjut.

Dave Kirby
sumber
Terima kasih dan ya, saya punya __init__.py. Masalahnya kali ini adalah dengan $PYTHONPATH. Solusi Ignacio berhasil.
bodacydo
1
File init .py diperlukan untuk membuat Python memperlakukan direktori sebagai paket yang berisi; ini dilakukan untuk mencegah direktori dengan nama umum, seperti string, menyembunyikan modul valid yang terjadi kemudian di jalur pencarian modul secara tidak sengaja. Dalam kasus yang paling sederhana, init .py hanya bisa menjadi file kosong
panofish
Terima kasih telah menyelamatkan saya kapan-kapan.
cpu_meltdown
9

Berikut ini solusi langkah demi langkah:

  1. Menambahkan script yang disebut run.pydalam /home/bodacydo/work/projectdan mengedit seperti ini:

    import programs.my_python_program
    programs.my_python_program.main()

    (ganti main()dengan metode yang setara di my_python_program.)

  2. Pergi ke /home/bodacydo/work/project
  3. Lari run.py

Penjelasan: Karena python menambahkan ke PYTHONPATH jalur skrip dari mana ia berjalan , berjalan run.pyakan menambahkan /home/bodacydo/work/project. Dan voila , import foo.tasksakan ditemukan.

cyborg
sumber
8

Contoh solusi untuk menambahkan perpustakaan ke PYTHONPATH Anda.

  1. Tambahkan baris berikut ke ~ / .bashrc Anda atau jalankan langsung:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. Kemudian tautkan pustaka yang Anda butuhkan ke folder ~ / .python, mis

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

Sebuah lebih baik memperbaiki daripada pengaturan PYTHONPATHadalah dengan menggunakanpython -m module.path

Ini akan diatur dengan benar sys.path[0]dan merupakan cara yang lebih andal untuk mengeksekusi modul.

Saya memiliki Langgan cepat tentang masalah ini, karena Penjawab lain telah disebutkan alasan untuk ini adalah python path/to/file.pymenempatkan path/topada awal PYTHONPATH( sys.path).

Anthony Sottile
sumber
2

Dalam pikiran saya, saya harus mempertimbangkan bahwa foofolder tersebut adalah perpustakaan yang berdiri sendiri. Saya mungkin ingin mempertimbangkan untuk memindahkannya ke Lib\site-packagesfolder dalam instalasi python. Saya mungkin ingin mempertimbangkan untuk menambahkan foo.pthfile di sana.

Saya tahu itu perpustakaan karena ./programs/my_python_program.pyberisi baris berikut:

from foo.tasks import my_function

Jadi tidak masalah itu ./programsfolder saudara ./foo. Ini fakta yang my_python_program.pydijalankan sebagai skrip seperti ini:

python ./programs/my_python_program.py

quamrana
sumber
0

Jika Anda mengalami masalah ini saat menggunakan versi instaled, saat menggunakan setup.py, pastikan modul Anda disertakan di dalamnyapackages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Danon
sumber