Python'da “ImportError: Adlandırılmış modül yok…” hatası nasıl düzeltilir?


115

Bu ImportError hatasını düzeltmenin doğru yolu nedir?

Aşağıdaki dizin yapısına sahibim:

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

Ve ben dizindeyim

/home/bodacydo/work/project

Şimdi yazarsam

python ./programs/my_python_program.py

Anında anlıyorum

ImportError: No module named foo.tasks

./programs/my_python_program.pyAşağıdaki satırı içerir:

from foo.tasks import my_function

Python'un neden bulamayacağını anlayamıyorum ./foo/tasks.py- orada.

Python kabuğundan yaparsam, işe yarıyor:

python
>>> from foo.tasks import my_function

Sadece python ./programs/my_python_program.pykomut dosyası yoluyla çağırırsam işe yaramaz .

Yanıtlar:


121

Python geçerli dizini sys.pathdeğil, betiğin bulunduğu dizini ekler . /home/bodacydo/work/projectYa sys.pathda $PYTHONPATH.


9
Öyleyse kök klasörde init .py olmasının anlamı nedir? Sys.path veya pythonpath 'i düzenlerseniz hiçbir amaca hizmet etmiyor gibi görünüyor.

11
@ Editör: __init__.pyyalnızca, dizinin üst öğesi sys.pathbir paketin içinde veya kendisi bir paket olduğunda, bir paket olarak ele alınması gerektiğini belirtir .
— Ignacio Vazquez-Abrams

3
Ayrıca klasör üzerindeki izinleri de kontrol edin. Benim durumumdaki sorun buydu.
— SidJ

15
Geçerli dizini python yoluna eklemek için şunu kullanınexport PYTHONPATH=`pwd`
— rodorgas

1
Benim için işe /home/bodacydo/work
— yarayan

33

__init__.pyFoo dizininde adlı bir dosyanız var mı? Aksi takdirde python, foo'yu bir python paketi olarak tanımaz.

Daha fazla bilgi için python öğreticisindeki paketlerle ilgili bölüme bakın .


Teşekkürler ve evet, yaptım __init__.py. Bu sefer sorun şuydu $PYTHONPATH. Ignacio'nun çözümü işe yaradı.
— bodacydo

1
İnit .py dosyaları Python paketlerini içeren dizinler olarak algılaması için gereklidir; bu, dize gibi ortak bir ada sahip dizinlerin, daha sonra modül arama yolunda ortaya çıkan geçerli modülleri istemeden gizlemesini önlemek için yapılır. En basit durumda, init .py boş bir dosya olabilir
— panofish

Bir ara beni kurtardığın için teşekkürler.
— cpu_meltdown

9

İşte adım adım çözüm:

  1. Bir denilen komut dosyasını ekleyin run.pyiçinde /home/bodacydo/work/projectböyle ve düzenle it:

    import programs.my_python_program
    programs.my_python_program.main()

    ( main()içindeki eşdeğer yönteminizle değiştirin my_python_program.)

  2. Git /home/bodacydo/work/project
  3. Çalıştırmak run.py

Açıklama: python , çalıştığı komut dosyasının yolunu PYTHONPATH'a run.pyeklediğinden , çalıştırma da eklenecektir /home/bodacydo/work/project. Ve voilà , import foo.tasksbulunacaktır.


8

Kitaplığı PYTHONPATH'ınıza eklemek için örnek çözüm.

  1. Aşağıdaki satırı ~ / .bashrc dosyanıza ekleyin veya doğrudan çalıştırın:

    export PYTHONPATH="$PYTHONPATH:$HOME/.python"
  2. Ardından gerekli kitaplığınızı ~ / .python klasörünüze bağlayın, örn.

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

6

Ayardan daha iyi bir düzeltme PYTHONPATHkullanmaktırpython -m module.path

Bu, doğru şekilde ayarlanacaktır sys.path[0]ve modülleri yürütmenin daha güvenilir bir yoludur.

Bir var çabuk writeup diğer answerers söylediğim gibi, bu sorun hakkında nedeni bu içindir python path/to/file.pykoyar path/tobaşında üzerinde PYTHONPATH( sys.path).


2

Aklımda, fooklasörün bağımsız bir kitaplık olduğunu düşünmem gerekiyor . Lib\site-packagesBir python kurulumundaki klasöre taşımayı düşünebilirim . Oraya bir foo.pthdosya eklemeyi düşünebilirim .

./programs/my_python_program.pyAşağıdaki satırı içerdiği için bir kütüphane olduğunu biliyorum :

from foo.tasks import my_function

Bu yüzden ./programskardeş klasör olması önemli değil ./foo. Bunun my_python_program.pygibi bir betik olarak çalıştırılan gerçek :

python ./programs/my_python_program.py


0

Yüklenmiş bir sürümü kullanırken bu sorunu yaşıyorsanız, kullanırken setup.py, modülünüzün içinde bulunduğundan emin olun.packages

setup(name='Your program',
    version='0.7.0',
    description='Your desccription',
    packages=['foo', 'foo.bar'], # add `foo.bar` here
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.