2012-01-21 17 views
54

Chcę zaimportować podfoldery jako moduły. Dlatego każdy podfolder zawiera __init__.py. Moja struktura folderów jest tak:Moduł importu z podfolderu

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

W moim głównym skrypcie importować

from dirFoo.foofactory import FooFactory 

W tym pliku fabrycznego I obejmuje moduły podrzędne:

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

Jeśli zgłoszę mój foofactory I uzyskać błąd, że python nie może zaimportować submodułów foo1 i foo2:

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 

Odpowiedz

79

Nie trzeba zadzierać ze swoim PYTHONPATH lub sys.path tutaj.

Aby prawidłowo korzystać z importu bezwzględne w opakowaniu należy uwzględnić "root" nazwa_pakietu, a także, np .:

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

Albo można użyć relative imports:

from .dirfoo1.foo1 import Foo1 
from .dirfoo1.foo1 import Foo2 
+24

Jedna rzecz do zapamiętania! dodaj '__init __. py' do każdego podfolderu, z którego importujesz. –

+3

Puste '__init __. Py' może wykonać zadanie. – cerebrou

+0

Jaka byłaby składnia, jeśli poprzednio 'Foo1' znajdował się w katalogu nadrzędnym, a jeden kodował coś podobnego' 'z importu Foo1 *'. Czy istnieje sposób na osiągnięcie tego samego efektu, więc nie trzeba poprzedzać wszystkiego 'Foo1'? – jxramos

3

Ustaw zmienną środowiskową PYTHONPATH. Na przykład taka jak ta PYTHONPATH =.: .. (dla rodziny * nix).

Ponadto można ręcznie dodać aktualny katalog (SRC w danym przypadku) do PYTHONPATH:

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

Wystarczy powiadomić tutaj. (od nowicjusza, keviv22)

Nigdy i na zawsze dla dobra własnego, nazwij foldery lub pliki spacjami lub symbolami jak "-" lub "_". Jeśli tak, możesz napotkać kilka problemów. jak moje, powiedzmy, chociaż twoje polecenie importowania jest poprawne, nie będziesz w stanie pomyślnie zaimportować pożądanych plików, które są dostępne wewnątrz takich nazwanych folderów.

Nieprawidłowe namings Folder w następujący sposób:

  • ogólne Klasy foldera
  • Generic_Classes_Folder

ważne namings Folder do powyżej:

  • GenericClassesFolder lub Genericclassesfolder lub genericClassesFolder (lub jak to bez żadnych spacji lub s Specjalny kosz symbole między słowami)

Co zrobiłem błąd:

pod uwagę strukturę plików.

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

Co chciałem zrobić?

  • z testFile.py, chciałem zaimportować 'targetClass.py 'wewnątrz pliku pliku klasy ogólnej, aby użyć funkcji o nazwie "functionExecute" w pliku "targetClass.py"

Jakie polecenie zrobiłem?

  • z '', napisał testFile.py polecenie, z Core.Generic-Class-Folder.targetClass importowej functionExecute
  • Got błędy takie jak "SyntaxError: Niepoprawna składnia"

próbowałem wielu wyszukiwania i obejrzał wiele pytań o stackoverflow i nie był w stanie zdecydować, co poszło nie tak. Sprawdzałem wielokrotnie moje pliki, użyłem pliku __init__.py, wstawiłem ścieżkę środowiska i ogromnie martwiłem się, co poszło nie tak ......

I po długim długim czasie, zrozumiałem to podczas rozmowy z przyjacielem kopalnia. Jestem trochę głupi, aby używać takich konwencji nazewnictwa. Nigdy nie powinienem używać spacji ani specjalnych symboli do definiowania nazwy dla dowolnego folderu lub pliku. Tak właśnie chciałem przekazać. Miłego dnia!

(przepraszam za ogromny post na ten temat ... po prostu pozwalam sobie na frustrację ...) Dzięki!)

+2

Spacje i myślniki ("-") spowodowałyby to, ale podkreślenia ("_") powinny nadal działać dobrze. – cowlinator