Import von Modulen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
headhunter1978
User
Beiträge: 20
Registriert: Sonntag 18. November 2018, 11:15

Hallo zusammen,

irgendwie habe ich Probleme richtig Module zu importieren. Ich möchte aus der modul1_file_1.py auf die Funktion say_hello() aus modul2_file_2.py zugreifen.

Ich benutze folgende Struktur.

Code: Alles auswählen

├── moduls
│   ├── __init__.py
│   ├── modul1
│   │   ├── __init__.py
│   │   └── modul1_file_1.py
│   └── modul2
│       ├── __init__.py
│       └── modul2_file_2.py
└── test
Auszug modul1_file_1.py

Code: Alles auswählen

from modul2.modul2_file_2 import *
 
say_hello()
Auszug modul2_file_2.py

Code: Alles auswählen

def say_hello():
	print ('Hello World')

say_hello()
Ich bekomme aber leider folgende Fehlermeldung:

Code: Alles auswählen

Traceback (most recent call last):
  File "modul1_file_1.py", line 1, in <module>
    from modul2.modul2_file_2 import *
ModuleNotFoundError: No module named 'modul2'
Habt ihr eine Idee was ich falsch mache.
Benutzeravatar
sparrow
User
Beiträge: 4231
Registriert: Freitag 17. April 2009, 10:28

In welchen Verzeichnissen nach nach Modulen gesucht wird, steht in sys.path. Beachte dort in der Doumemtation auch den Eintrag zu einem leeren String in der Liste.

Dann musst du dir überlegen wo das Wurzelverzeichnis deines Programms ist, und wie man vonr dort über die Pfade zu dem Modul kommt, dass du importieren willst. Jedes Verzeichnis stellt eine Ebene dar.
headhunter1978
User
Beiträge: 20
Registriert: Sonntag 18. November 2018, 11:15

Muss ich zwingend sys.path erweitern? Ich bin davon ausgegangen, dass die Module automatisch gefunden werden bzw. durch die Datei __init__.py das erfolgt.
Benutzeravatar
__blackjack__
User
Beiträge: 13199
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@headhunter1978: Das oberste Package muss über einen Eintrag `sys.path` zu finden sein. Da ist normalerweise das aktuelle Arbeitsverzeichnis drin und installierte Packages. Python fängt nicht an irgendwo auf der Plattte nach `__init__.py`-Dateien zu suchen.

Das nächste ist, dass es auch dann kein `modul2` geben wird. Es gibt `moduls`. Und darin ein `modul2`. Also muss der Import dann ``from moduls.modul2.modul2_file_2 import say_hello`` lauten. Das mit dem Sternchen solltest Du gar nicht erst anfangen.

Und Du startest das hoffentlich auch richtig: ``python -m moduls.modul1.modul1_file_1`` — und nicht die *.py-Datei als wäre das ein Skript, denn dann kann man auch Probleme bekommen weil zum Beispiel dann die `__init__.py` auf dem Weg dort hin vorher nicht ausgeführt werden und man das Modul dann über zwei verschiedene Wege erreicht und es so zweimal importiert werden kann.

Die Namen der Packages und Module sind auch für Demozwecke ziemlich redundant, und inhaltlich natürlich auch nicht ganz richtig wenn man Packages als Module bezeichnet.

Eingerückt wird mit vier Leerzeichen pro Ebene, nicht mit Tabs.

Edit: Um noch mal auf den ersten Absatz zu kommen: Entweder startet man das ganze so dass das oberste Package im aktuellen Arbeitsverzeichnis liegt, oder man installiert das Package. Das kann man auch in einem virtualenv machen und/oder ``--editable`` wenn man an dem Package/Programm arbeitet. An `sys.path` selbst zu arbeiten ist eher eine gehackte Lösung IMHO.
“There will always be things we wish to say in our programs that in all known languages can only be said poorly.” — Alan J. Perlis
Antworten