2015-06-05 12 views
39

sembra che ci siano già abbastanza alcune domande qui circa l'importazione relativa a Python 3, ma dopo aver attraversato molti di loro ancora non ha trovato la risposta per il mio problema. quindi ecco la domanda.al di là di alto livello errore pacchetto in importazione relativo

ho un pacchetto illustrato di seguito

package/ 
    __init__.py 
    A/ 
     __init__.py 
     foo.py 
    test_A/ 
     __init__.py 
     test.py 

e ho una sola riga in test.py:

from ..A import foo 

ora, sono nella cartella di package, e corro

python -m test_A.test 

ho avuto un messaggio

"ValueError: attempted relative import beyond top-level package" 

ma se mi trovo in cartella principale di package, per esempio, corro:

cd .. 
python -m package.test_A.test 

tutto va bene.

ora la mia domanda è: quando sono nella cartella di package, e corro il modulo all'interno del sub-package test_A come test_A.test, in base alla mia comprensione, ..A va su un solo livello, che è ancora all'interno della package cartella, perché fornisce un messaggio che dice beyond top-level package. Qual è esattamente la ragione che causa questo messaggio di errore?

+0

possibile duplicato di [Come fare le importazioni relative a Python?] (Http://stackoverflow.com/questions/72852/how-to- do-relative-imports-in-python) – SimKev2

+4

il post non spiegava il mio errore "oltre il livello superiore" – shelper

+0

Ho un pensiero qui, quindi quando esegui test_A.test come modulo, '..' va sopra test_A, che è già il livello più alto di importazione test_A.test, penso che il livello del pacchetto non sia il livello della directory, ma quanti livelli si importano il pacchetto. – shelper

risposta

21

Assunzione:
Se ci si trova nella directory package, A e test_A sono pacchetti separati.

Conclusione:
..A le importazioni sono consentite solo all'interno di un pacchetto.

Ulteriori note:
Fare le importazioni relative disponibili solo all'interno di pacchetti è utile se si desidera imporre che i pacchetti possono essere immessi in qualsiasi percorso situato sul sys.path.

+12

Sono l'unico a pensare che sia pazzesco? Perché nel mondo la directory corrente non è considerata un pacchetto? – Multihunter

8
import sys 
sys.path.append("..") # Adds higher directory to python modules path. 

Prova questo. ha funzionato per me.

7

Perché non funziona? È perché python non registra da dove è stato caricato un pacchetto. Così, quando lo fai python -m test_A.test, è fondamentalmente solo scarta la consapevolezza che test_A.test effettivamente memorizzata nei package (vale a dire package non è considerato un pacchetto). Il tentativo di from ..A import foo sta tentando di accedere alle informazioni che non ha più (cioè le directory di pari livello di una posizione caricata). È concettualmente simile a consentire from ..os import path in un file in math. Questo sarebbe male perché vuoi che i pacchetti siano distinti. Se hanno bisogno di usare qualcosa da un altro pacchetto, allora dovrebbero fare riferimento a loro in tutto il mondo con from os import path e lasciare che Python risolva il problema con $PATH e $PYTHONPATH.

Quando si utilizza python -m package.test_A.test, quindi l'utilizzo di from ..A import foo risolve correttamente perché ha tenuto traccia di ciò che è in package e si sta appena accedendo a una directory secondaria di una posizione caricata.

Perché python non considera la directory di lavoro corrente come un pacchetto?NO CLUE, ma diamine sarebbe utile.

-1

from package.A import foo

penso che sia più chiaro che

import sys 
sys.path.append("..")