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.