2012-07-09 11 views
13

Sono la seguente struttura del codice sorgentePython package import dalla directory padre

/testapp/ 
/testapp/__init__.py 
/testapp/testmsg.py 
/testapp/sub/ 
/testapp/sub/__init__.py 
/testapp/sub/testprinter.py 

dove testmsg definisce la seguente costante:

MSG = "Test message" 

e sub/testprinter.py:

import testmsg 

print("The message is: {0}".format(testmsg.MSG)) 

Ma io sto ottenendo ImportError: No module named testmsg

Non dovrebbe funzionare dopo la struttura del pacchetto? Non voglio davvero estendere sys.path in ogni sottomodulo e non voglio nemmeno usare l'importazione relativa.

Cosa sto facendo di sbagliato qui?

+0

Come si esegue il codice? –

+0

@SimeonVisser che esegue 'python sub/testprinter.py', ma anche' python testprinter.py' nella directory 'sub' non funziona. –

risposta

8

Tutto dipende da quale è scritto run. Il percorso di questo script verrà aggiunto automaticamente al percorso di ricerca di python.

Ne fanno la seguente struttura:

TestApp/ 
TestApp/README 
TestApp/LICENSE 
TestApp/setup.py 
TestApp/run_test.py 
TestApp/testapp/__init__.py 
TestApp/testapp/testmsg.py 
TestApp/testapp/sub/ 
TestApp/testapp/sub/__init__.py 
TestApp/testapp/sub/testprinter.py 

Poi gestita TestApp/run_test.pyprimo:

from testapp.sub.testprinter import functest ; functest() 

Poi TestApp/testapp/sub/testprinter.py potrebbe fare:

from testapp.testmsg import MSG 
print("The message is: {0}".format(testmsg.MSG)) 

Più buone note here;

+0

può dipendere dal fatto che non ho generato un file setup.py? Quello che voglio dire è che ho seguito la struttura del pacchetto Python ma non ho generato il metodo di installazione, assumendo che potesse funzionare anche senza dover installare 'setup.py install '. –

+0

@CodeShining, no non importa. Ho incluso solo 'setup.py' nell'esempio per chiarezza. Ciò che conta davvero, come ho detto nel primo paragrafo della risposta, è ** quale file stai correndo al primo posto **. Se avvii (esegui) un file all'interno del pacchetto, questo non vedrà il pacchetto. Quindi è una buona pratica avere il tuo copione principale (quello che ** fai **) al di fuori del pacchetto. – nosklo

6

Usa importazione relativa come qui di seguito

from .. import testmsg 
+0

ma essendo un pacchetto non dovrebbe funzionare come previsto? Non userei il parente se è previsto che funzioni –

+0

CodeShining, guarda la decisione di Dido per python 3.5 PEP-328 per standard. [link] (http://www.python.org/dev/peps/pep-0328/#guido-s-decision) –

4

Questa domanda è la risposta - importazione dinamica:

How to import a python file in a parent directory

import sys 
sys.path.append(path_to_parent) 
import parent.file1 

Ecco qualcosa che ho fatto per importare nulla. Naturalmente, devi ancora copiare questo script nelle directory locali, importarlo e use il percorso che desideri.

import sys 
import os 

# a function that can be used to import a python module from anywhere - even parent directories 
def use(path): 
    scriptDirectory = os.path.dirname(sys.argv[0]) # this is necessary to allow drag and drop (over the script) to work 
    importPath = os.path.dirname(path) 
    importModule = os.path.basename(path) 
    sys.path.append(scriptDirectory+"\\"+importPath)  # Effing mess you have to go through to get python to import from a parent directory 

    module = __import__(importModule) 
    for attr in dir(module): 
     if not attr.startswith('_'): 
      __builtins__[attr] = getattr(module, attr)