2017-03-20 3 views
0

Ich habe eine Python-Bibliothek, die wie folgt aussieht (enthält Pakete):Vieldeutigkeit der Importmodule in Python

|-- python_lib/ 
    |-- plotting.py 
    |-- verification.py 
    |-- io.py 
    | 
    |-- ensemble/ 
     | -- plotting.py 
     | -- verification.py 

Aber ich habe Probleme mit mehrdeutigen Modul importiert. In ensemble.plotting.py mag ich das verification.py Modul von der obersten Ebene importieren (python_lib):

# ensemble/plotting.py 
import verification.obs as verobs 

Allerdings bekomme ich einen Importfehler, da dies das verification.py Modul aus dem Ensemble Verzeichnis zu importieren versucht, statt der oberste Ebene die Bibliothek.

Ich dachte, dass die „abslute Importe“ -Funktion dieses Problem lösen würde:

from ..verification import obs 

aber ich bekomme diese Fehlermeldung:

ValueError: Attempted relative import beyond toplevel package 

Wie richte ich python_lib/verification.py als Import von python_lib/ensemble/*.py ohne zu versuchen, die lokale Paketversion importieren?

Ich benutze Python Version 2.7.

+3

'von python_lib.verification importieren obs'? – leovp

+0

@leovp python_lib ist kein Paket, es passiert einfach mit dem Basisverzeichnis, in dem sich die Quelle befindet. – ccbunney

+0

Versuchen Sie, jede leere Unterdatei namens __init__.py hinzuzufügen. betrachten Sie diese https://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py?rq=1 auch – nivhanin

Antwort

0

Es ist eine hacky Lösung, die funktionieren würde, aber im Allgemeinen wird abgeraten.

Sie können Python-Pfad an Stelle ändern, wenn Sie Konflikte auslassen müssen. Wie folgt aus:

import sys # needed to make it work 

tmp = sys.path[0] 
sys.path = sys.path[1:] # ugly and hacky thingy 

# import stuff you need (would work with __init__.py in a base dir) 
from python_lib import verification 
from ..verification.obs import obs 

# fix path back 
sys.path.insert(0, tmp) 

ich dieses Muster nur getestet und es scheint zu funktionieren (Python 3.6.0)

1
  1. Alle Ihre Verzeichnisse Dateien __init__.py enthalten sollte, oder sie werden nicht als Pakete erkannt werden .

  2. Ihr Verzeichnis python_lib muss ein bekannter Pfad sein. Du hast in einem Kommentar gesagt, dass dein PYTHONPATH einen Pfad zu python_lib enthält, das scheint also gut zu sein.

  3. Wenn Sie mit z. python_lib/ensemble/verification.py Als Haupteinstiegspunkt, dann das Verzeichnis python_lib/ensemble Schatten Ihr Verzeichnis python_lib, und Sie müssen Python manuell sagen, dass Ihr Skript zu diesem Paket gehört.

So:

if __name__ == "__main__" and __package__ is None: 
    __package__ = "pythonlib.ensemble" 
    import pythonlib 

Nachdem dies geschehen ist, sollte diese Arbeit:

from ..verification import obs 
0

Es gibt einige Regeln, die befolgt werden muss, während Pakete und Module zu erstellen.

  1. Stellen Sie sicher, dass es __init__.py Datei als Teil Ihres Pakets gibt. Jedes Python-Paket muss diese Datei haben
  2. Während das Modul betrachtet wird, geschieht es auf drei Arten.

Eine sehr gute Dokumentation ist Module-search-path

Normalerweise beim Aufbau Projekte es sich um eine Praxis, eine Lib-Paket zu erstellen und Unterverzeichnisse auf der Basis verschiedener Kategorien hinzufügen und das Hauptverzeichnis der PYTHONPATH Variable hinzuzufügen. Dies macht das Modul für andere Programme verfügbar.