2012-01-21 11 views
54

Desidero importare sottocartelle come moduli. Pertanto ogni sottocartella contiene __init__.py. La mia struttura di cartelle è come questo:Importare modulo dalla sottocartella

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

Nel mio script principale importare

from dirFoo.foofactory import FooFactory 

In questo file fabbrica includo i moduli secondari:

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

Se chiamo il mio foofactory I ottenere l'errore, che python non può importare i sottomodelli foo1 e 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 

risposta

79

Non c'è bisogno di pasticciare con il vostro PYTHONPATH o sys.path qui.

Per utilizzare correttamente le importazioni assoluti in un pacchetto che dovrebbe includere la packagename "root", così, ad es .:

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

oppure è possibile utilizzare relative imports:

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

Una cosa da ricordare! aggiungi '__init __. py' a ogni sottocartella da cui stai importando. –

+3

Vuoto '__init __. Py' può fare il lavoro. – cerebrou

+0

Quale sarebbe la sintassi se in precedenza 'Foo1' si trovava nella directory padre e uno codificasse qualcosa come' da Foo1 import * '. C'è un modo per ottenere lo stesso effetto in modo da non dover prefissare tutto con 'Foo1'? – jxramos

3

Imposta la variabile di ambiente PYTHONPATH. Ad esempio, come questo PYTHONPATH =.: .. (per la famiglia * nix).

Inoltre è possibile aggiungere manualmente la directory corrente (src nel tuo caso) per PYTHONPATH:

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

Proprio per notificare qui. (da una newbee, keviv22)

Mai e poi mai per il tuo bene, chiama le cartelle oi file con spazi o simboli come "-" o "_". Se lo facessi, potresti affrontare alcuni problemi. come il mio, per esempio, sebbene il tuo comando per l'importazione sia corretto, non sarai in grado di importare con successo i file desiderati che sono disponibili all'interno di tali cartelle.

namings non validi cartella come segue:

  • generici-Classes-folder
  • Generic_Classes_Folder

namings cartella valida per sopra:

  • GenericClassesFolder o Genericclassesfolder o genericClassesFolder (o come questo senza spazi o s simboli peciali tra le parole)

Che errore che ho fatto:

considerano la struttura dei file.

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

Cosa volevo fare?

  • da testFile.py, volevo importare il 'targetClass.py 'file all'interno del file di classe generica per utilizzare la funzione denominata "functionExecute" nel file' targetClass.py '

Che comando ho fatto?

  • da 'testFile.py', il comando, scritto da Core.Generic-Class-Folder.targetClass importazione functionExecute
  • Got errori come "SyntaxError: la sintassi non valida"

provato molte ricerche e ha visto molte domande sullo stackoverflow e non è stato in grado di decidere cosa è andato storto. Ho incrociato più volte i miei file, ho usato il file __init__.py, ho inserito il percorso dell'ambiente e mi sono preoccupato enormemente di quello che è andato storto ......

E dopo tanto, tanto tempo ho capito mentre parlavo con un amico di il mio. Sono un po 'stupido usare queste convenzioni sui nomi. Non dovrei mai usare lo spazio o simboli speciali per definire un nome per qualsiasi cartella o file. Quindi, questo è quello che volevo trasmettere. Buona giornata!

(scusate per l'enorme posta su questo ... solo lasciando le mie frustrazioni andare .... :) Grazie!)

+2

Spaces e dashes ("-") causerebbero questo, ma i caratteri di sottolineatura ("_") dovrebbero comunque funzionare correttamente. – cowlinator