Modülü alt klasörden içe aktar


104

Alt klasörleri modüller olarak içe aktarmak istiyorum. Bu nedenle her alt klasör bir __init__.py. Klasör yapım şöyle:

src\
  main.py
  dirFoo\
    __init__.py
    foofactory.py
    dirFoo1\
      __init__.py
      foo1.py
    dirFoo2\
      __init__.py
      foo2.py

Ana komut dosyamda içe aktarıyorum

from dirFoo.foofactory import FooFactory

Bu fabrika dosyasına alt modülleri ekledim:

from dirFoo1.foo1 import Foo1
from dirFoo2.foo2 import Foo2

Foofactory'mi çağırırsam, bu python foo1 ve foo2 alt modüllerini içe aktaramaz:

Traceback (most recent call last):
  File "/Users/tmp/src/main.py", line 1, in <module>
from dirFoo.foofactory import FooFactory
  File "/Users/tmp/src/dirFoo/foofactory.py", line 1, in    <module>
from dirFoo1.foo1 import Foo1
    ImportError: No module named dirFoo1.foo1

Yanıtlar:


137

Seninle PYTHONPATHya da sys.pathburada uğraşmana gerek yok.

Bir pakette mutlak içe aktarımları doğru şekilde kullanmak için "kök" paket adını da eklemelisiniz, örneğin:

from dirFoo.dirFoo1.foo1 import Foo1
from dirFoo.dirFoo2.foo2 import Foo2

Veya göreli ithalatı kullanabilirsiniz :

from .dirfoo1.foo1 import Foo1
from .dirfoo2.foo2 import Foo2

47
Hatırlanması gereken bir şey! __init__.pyiçe aktardığınız her alt klasöre ekleyin .
Aziz Alto

6
Boş __init__.pyiş yapabilir.
cerebrou

1
Daha önce Foo1ana dizinde olsaydı ve biri gibi kodlanmış olsaydı sözdizimi ne olurdu from Foo1 import *? Her şeyin önekini koymak zorunda kalmamak için aynı etkiyi elde etmenin bir yolu var mı Foo1?
jxramos

1
@AzizAlto: Yorumunuz olmadan bu çözüm pek kullanışlı değil
Alex

21

Sadece buradan haberdar etmek için. (bir newbee'den, keviv22)

Hiçbir zaman ve asla kendi iyiliğiniz için, klasörleri veya dosyaları "-" veya "_" gibi sembollerle adlandırmayın. Bunu yaptıysanız, birkaç sorunla karşılaşabilirsiniz. Benimki gibi, diyelim ki, içe aktarma komutunuz doğru olsa da, bu tür adlandırılmış klasörler içinde bulunan istenen dosyaları başarılı bir şekilde içe aktaramazsınız.

Geçersiz Klasör adları aşağıdaki gibidir:

  • Genel Sınıflar Klasörü
  • Generic_Classes_Folder

Yukarıdakiler için geçerli Klasör adları:

  • GenericClassesFolder veya Genericclassesfolder veya genericClassesFolder (veya kelimeler arasında boşluk veya özel semboller olmadan bunun gibi)

Ne hata yaptım:

dosya yapısını düşünün.

Parent
   . __init__.py
   . Setup
     .. __init__.py
     .. Generic-Class-Folder
        ... __init__.py
        ... targetClass.py
   . Check
     .. __init__.py
     .. testFile.py

Ne yapmak istedim

  • testFile.py'den, 'targetClass.py' dosyasında "functionExecute" adlı işlevi kullanmak için Generic-Class-Folder dosyasındaki 'targetClass.py' dosyasını içe aktarmak istedim

Ne emri verdim?

  • 'testFile.py'den komut yazdı, from Core.Generic-Class-Folder.targetClass import functionExecute
  • Gibi hatalar var SyntaxError: invalid syntax

Birçok arama denedi ve birçok yığın akışı sorusunu görüntüledi ve neyin yanlış gittiğine karar veremedi. Dosyalarımı defalarca kontrol ettim, __init__.pydosya kullandım , ortam yolunu ekledim ve neyin yanlış gittiğinden çok endişelendim ......

Ve uzun uzun bir süre sonra bunu bir arkadaşımla konuşurken anladım. Bu tür adlandırma kurallarını kullanmak konusunda biraz aptalım. Herhangi bir klasör veya dosya için isim tanımlamak için asla boşluk veya özel semboller kullanmamalıyım. Yani, iletmek istediğim şey bu. İyi günler!

(bununla ilgili büyük gönderi için özür dilerim ... sadece hayal kırıklıklarımı bırakıyorum .... :) Teşekkürler!)


23
Boşluklar ve kısa çizgiler ("-") buna neden olur, ancak alt çizgiler ("_") yine de düzgün çalışmalıdır.
cowlinator

6

PYTHONPATH ortam değişkeninizi ayarlayın. Örneğin, PYTHONPATH =.: .. (* nix ailesi için) gibi.

Ayrıca mevcut dizininizi (sizin durumunuzda src) pythonpath'e manuel olarak ekleyebilirsiniz:

import os
import sys
sys.path.insert(0, os.getcwd())

2

Projenizin şu şekilde yapılandırıldığını varsayalım:

+---MyPythonProject
|   +---.gitignore
|   +---run.py
|   |   +---subscripts
|   |   |   +---script_one.py
|   |   |   +---script_two.py

İçeride run.py, bir ve iki komut dosyalarını şu şekilde içe aktarabilirsiniz:

from subscripts import script_one as One
from subscripts import script_two as Two

Şimdi, hala içeride run.py, yöntemlerini şu şekilde çağırabileceksiniz:

One.method_from_one(param)
Two.method_from_two(other_param)

1

Sadece boş bir ___init____.py dosyası oluşturun ve bunu hem kök dizinine hem de diğer python modüllerinin olduğu python uygulamanızın tüm alt dizinine / klasörüne ekleyin.


-2

Alt klasörde init .py olsa bile sorunlar vardı ve eksik olan tek şey içe aktarmadan sonra "as" ekliyordu

from folder.file import Class as Class
import folder.file as functions
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.