2015-06-05 4 views
39

Es scheint, es gibt schon einige Fragen über den relativen Import in Python 3, aber nach vielen durchläuft ich immer noch nicht die Antwort für mein Problem. also hier ist die Frage.über Top-Level-Paket Fehler im relativen Import

Ich habe ein Paket unten gezeigt

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

und ich habe nur eine einzige Zeile in test.py:

from ..A import foo 

jetzt, ich bin in dem Ordner von package, und ich laufe

python -m test_A.test 

Ich habe Nachricht

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

aber wenn ich in den übergeordneten Ordner von package bin, zum Beispiel, ich laufe:

cd .. 
python -m package.test_A.test 

alles ist in Ordnung.

jetzt meine Frage ist: wenn ich im Ordner von package bin, und ich führen Sie das Modul innerhalb des Test_a Unterpaket als test_A.test, basierend auf meinem Verständnis geht ..A nur eine Ebene nach oben, die package innerhalb der nach wie vor ist Ordner, warum gibt es eine Nachricht sagen beyond top-level package. Was ist genau der Grund, der diese Fehlermeldung verursacht?

+0

möglich Duplikat von [Wie relativ Einfuhren in Python zu tun?] (Http://stackoverflow.com/questions/72852/how-to- Do-Relative-Importe-in-Python) – SimKev2

+4

dieser Beitrag hat nicht mein "jenseits des Top-Level-Pakets" Fehler – shelper

+0

Fehler Ich habe einen Gedanken hier, also, wenn test_A.test als Modul ausgeführt, '..' geht über test_A, die ist bereits die höchste Ebene des Imports test_A.test, ich denke, die Paketstufe ist nicht die Verzeichnisebene, sondern wie viele Ebenen Sie das Paket importieren. – shelper

Antwort

21

Annahme:
Wenn Sie im package Verzeichnis sind, A und test_A sind separate Pakete.

Fazit:
..A Importe sind nur innerhalb eines Pakets erlaubt.

Weitere Hinweise:
machen die relativen Importe innerhalb von Paketen nur verfügbar ist nützlich, wenn Sie erzwingen möchten, dass Pakete können auf jedem auf sys.path befindet Weg gelegt werden.

+12

Bin ich der einzige, der das für verrückt hält ?! Warum in der Welt wird das laufende Verzeichnis nicht als Paket betrachtet? – Multihunter

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

Versuchen Sie dies. Arbeitete für mich.

7

Warum funktioniert es nicht? Es ist, weil Python nicht aufzeichnet, wo ein Paket geladen wurde. Also, wenn Sie python -m test_A.test tun, verwirft es im Grunde nur das Wissen, dass test_A.test tatsächlich in package gespeichert ist (d. H. package wird nicht als ein Paket betrachtet). Beim Versuch, from ..A import foo zu versuchen, auf Informationen zuzugreifen, die es nicht mehr hat (d. H. Geschwisterverzeichnisse eines geladenen Orts). Es ist konzeptionell ähnlich zu ermöglichen from ..os import path in einer Datei in math. Dies wäre schlecht, weil die Pakete unterschiedlich sein sollen. Wenn sie etwas aus einem anderen Paket verwenden müssen, sollten sie sich global auf sie beziehen mit from os import path und python herausfinden, wo das ist mit $PATH und $PYTHONPATH.

Wenn Sie python -m package.test_A.test verwenden, löst die Verwendung from ..A import foo nur gut, weil es verfolgt, was in package ist, und Sie nur auf ein untergeordnetes Verzeichnis eines geladenen Speicherort zugreifen.

Warum betrachtet Python das aktuelle Arbeitsverzeichnis nicht als Paket?KEIN CLUE, aber Gott wäre es nützlich.

-1

from package.A import foo

Ich denke, es ist klarer als

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