Hallo,
ich bin derzeit dabei mein Python Prgramm zu modularisieren.
Ich nutze Pycharme auf Win 7.
Ich habe verschiedene Pythonfiles, die in unterschiedlichen Ordnern liegen, die dann aufgerufen werden sollen, um das Programm besser lesbar zu machen.
Konkret sieht das gaze so aus:
Main-Ordner-A
-----Sub-Ordner B
----------Python-Modul 1
----------Python Modul 2
-----Python Modul 3
Ich möchte nun im dritten Pythonmodul die beiden anderen Module verweden. also:
modul3 hat am anfang import B.modul2 und B.modul1
modul2 jedoch braucht zum funktionieren modul1, und wenn ich mein modul3 jetzt ausführe sagt er, dass "No module named modul1" existiert.
Ich hoffe das war nicht zu verwirrend; falls das zu allgemein forumliert war, kann ich gerne konkreter werden.
Viele Dank für die Hilfe
Ewkos
Module in Python
@Ewkos: Wenn Du zirkuläre Importe machst, oder versuchst zu machen, denn das ist ziemlich tricky überhaupt richtig hinzubekommen, dann ist die Aufteilung auf Module ziemlich sicher falsch.
Hi, also ein Zirkelaufruf habe ich nicht.
Modul 3 verwendet Modul 1 und 2 und Modul 2 nutzt Modul 1.
Ich konnte es nun lösen, indem ich bei Modul 2 folgendes verwende:
from . import module1
Damit kann ich Modul 2 leider nur noch importiert verwenden und nicht mer allein; gibt es auch dafür eine Lösung?
Modul 3 verwendet Modul 1 und 2 und Modul 2 nutzt Modul 1.
Ich konnte es nun lösen, indem ich bei Modul 2 folgendes verwende:
from . import module1
Damit kann ich Modul 2 leider nur noch importiert verwenden und nicht mer allein; gibt es auch dafür eine Lösung?
@Ewkos: Wenn Du keinen Kreis in den Abhängigkeiten hast, dann verstehe ich das Problem nicht. Und ich verstehe auch nicht wieso Du `module2` nicht ”allein” verwenden kannst?
Ich denke Du machst da etwas falsch. Kann es sein das Du das nicht sauber als Package verwendest sondern versuchst Module *in* einem Package als Programme auszuführen ohne über das Package zu gehen? Und beim Importieren vielleicht das gleiche: Teile innerhalb eines Packages gleichzeitig im Pfad für Python-Module zu verwenden, führt zu Chaos und ist so nicht vorgesehen.
Ich denke Du machst da etwas falsch. Kann es sein das Du das nicht sauber als Package verwendest sondern versuchst Module *in* einem Package als Programme auszuführen ohne über das Package zu gehen? Und beim Importieren vielleicht das gleiche: Teile innerhalb eines Packages gleichzeitig im Pfad für Python-Module zu verwenden, führt zu Chaos und ist so nicht vorgesehen.
Bei mir sieht es nun so aus:
### /module3.py
import B.module2
### /B/module2.py
from . import module1
### /B/module1.py
# macht iwas
So funktioinert dann modul3 korrekt, aber so ist modul 2 nicht mehr ausführbar.
Das ersteres funktioniert, liegt daran, dass das file im aktuellen ordner gescuht werden soll, wenn modul 2 aufgerufen wird, aber falls ich modul 2 allein verwenden will, ist dieser "." unnötig und ich könnte ganz normal import modul 1 schreiben.
### /module3.py
import B.module2
### /B/module2.py
from . import module1
### /B/module1.py
# macht iwas
So funktioinert dann modul3 korrekt, aber so ist modul 2 nicht mehr ausführbar.
Das ersteres funktioniert, liegt daran, dass das file im aktuellen ordner gescuht werden soll, wenn modul 2 aufgerufen wird, aber falls ich modul 2 allein verwenden will, ist dieser "." unnötig und ich könnte ganz normal import modul 1 schreiben.
@Ewkos: Du machst das wie schon gesagt falsch. Du kannst und solltest nicht `module2` ausführen, denn `module2` gibt es gar nicht. Das ist Teil des Packages `B`. Und so kann und muss man das dann auch ausführen als `B.module2`. Python hat da die Option `-m` für, also ``python -m B.module2 …``. Und dabei sollte man auch auf keinen Fall als aktuelles Arbeitsverzeichnis ``…/B/`` haben, denn das sind die Module im Package `B` entweder nur oder sogar gleichzeitig direkt und über das Package importierbar, was falsch ist und zu lustigen Effekten führen kann, die man nicht haben möchte.
@Ewkos: als Hauptprogramm ausgeführte Module können keine relativen Importe vornehmen. In Python3 (ab 3.6) führt dies zu einem ImportError, bei früheren Version sind die Fehlermeldungen andere (SystemError etc.).
Ein Workaround in Python 3.6 wäre das folgende in module2:
Ein Workaround in Python 3.6 wäre das folgende in module2:
Code: Alles auswählen
try:
from . import module1
except ImportError:
import module1
@kbr: Das wäre aber falsch, weil es ja a) weiter die Probleme hat das plötzlich Module über mehr als einen Weg importierbar sind, und alles auf gleicher Ebene, also die Module/Packages *in* dem Package plötzlich auf der obersten Ebene als Importe zur Verfügung stehen, was auch wieder Probleme bereiten kann wenn die den gleichen Namen wie beispielsweise ein Modul aus der Standardbibliothek haben. Und b) gibt es ja mit der ``-m``-Option einen offiziellen Weg Module in Packages als Programme auszuführen. Und dabei treten diese Probleme nicht auf.
@BlackJack: das kann man durchaus machen umgerade gezielt dafür zu sorgen, dass Module über mehr als einen Weg importierbar sind. Es ist in der Situation aber sicher richtig sich zu fragen, ob ein berechtigter Spezialfall vorliegt oder das Problem eher auf einen Entwurffehler hindeutet (was meistens der Fall sein dürfte). Abgesehen davon sehen die import-header unschön aus – allein das wäre schon ein Grund für jeden Python-Ästheten sowas möglichst zu vermeiden.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Soweit ich das sehe, geht es nicht um zirkularen Import, der auch einfach zu machen wäre.
Sondern wenn man von einem Unterverzeichnis importieren will, muss man vorher dort eine leere Datei namens '__init__.py' anlegen.
Wenn sich zwei Module gegenseitig importieren müssen, dann geht das auch einfach. Das eine Modul import das andere zu Beginn, das andere dieses ganz am Ende. Das geht aber nur, wenn beim anderen Modul Referenzen auf etwas im einen Modul nur innerhalb von Funktionen oder Methoden vorkommen, die nicht schon beim import aufgerufen werden.
Sondern wenn man von einem Unterverzeichnis importieren will, muss man vorher dort eine leere Datei namens '__init__.py' anlegen.
Wenn sich zwei Module gegenseitig importieren müssen, dann geht das auch einfach. Das eine Modul import das andere zu Beginn, das andere dieses ganz am Ende. Das geht aber nur, wenn beim anderen Modul Referenzen auf etwas im einen Modul nur innerhalb von Funktionen oder Methoden vorkommen, die nicht schon beim import aufgerufen werden.
@Alfons Mittelmeyer: __init__.py ist bei Python 3 nicht mehr nötig. Importe sollten immer am Anfang der Datei stehen. Das ist auch bei zirkulären Importen - sollten sie denn wirklich nötig sein - der Fall.
@kbr: solcher Import-Wodoo sollte nie nötig sein, wenn man Packages so einsetzt, wie sie gedacht sind. Alles andere führt im besten Fall zu Namenschaos.
@kbr: solcher Import-Wodoo sollte nie nötig sein, wenn man Packages so einsetzt, wie sie gedacht sind. Alles andere führt im besten Fall zu Namenschaos.
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Das geht aber nicht. Hier ein Beispiel:Sirius3 hat geschrieben: Importe sollten immer am Anfang der Datei stehen. Das ist auch bei zirkulären Importen - sollten sie denn wirklich nötig sein - der Fall.
@kbr: solcher Import-Wodoo sollte nie nötig sein, wenn man Packages so einsetzt, wie sie gedacht sind. Alles andere führt im besten Fall zu Namenschaos.
Code: Alles auswählen
import DynTkInter as tk
from tkinter import ttk as StatTtk
class Label(tk.GuiElement,StatTtk.Label):
def __init__(self,myname=None,**kwargs):
tk._initGuiElement(kwargs,StatTtk.Label,self,myname,"label")
DynTkInter muss auch dieses Modul Importieren, weil dort abgefragt wrid ob ein PanedWindow nun ein eigenes PanedWindow (StatTkInter.PanedWindow) oder eines von diesem Modul ist (StatTtk.PanedWindow). So etwas kommt aber erst nach dem Import der Module vor. Daher kann das einfach dadurch gelöst werden, dass DynTkInter dieses Modul DynTtk am Ende importiert.
Ein Import am Anfang geht dagegen nicht. Würde DynTkInter das Modul DynTtk am Anfang importieren, und würde dann DynTtk auch DynTkInter am Anfang importieren, dann geht das nicht, weil der import von DynTkInter noch gar nicht abgeschlossen ist, sondern lediglich an der Stelle steht, wo der import von DynTtk stattfindet.
Man kann nur etwas importieren, wenn etwas noch nicht importiert wurde, oder wenn der import soweit abgeschlossen ist, soweit man das braucht. Normalerweise würde man es wohl bis zum Ende brauchen und daher den import ganz am Ende tun. Wäre auch übersichtlicher als mittendrin, auch wenn das eine Modul nicht alles vom anderen braucht.
Danke erstmal für die bisherige Hilfe!
Also sollte ich Modul2 nicht seperat ausführen, ok.
Nochmal eine Frage:
Ich habe folgende Ordnerstruktur und möchte wieder importieren:
Main-Ordner
- Ordner A
--main.py
-Ordner B
--test.py
Nun möchte ich test.py in main.py verwenden. Wie muss ich importieren, um das zu erreichen?
Bisher mache ich das so, aber es funktioniert nicht:
import sys
sys.path.append(".")
from B import test
Nun erhalte ich den folgenden Fehler:
ImportError: No module named 'data'
Vielen Dank für die Hilfe!
Also sollte ich Modul2 nicht seperat ausführen, ok.
Nochmal eine Frage:
Ich habe folgende Ordnerstruktur und möchte wieder importieren:
Main-Ordner
- Ordner A
--main.py
-Ordner B
--test.py
Nun möchte ich test.py in main.py verwenden. Wie muss ich importieren, um das zu erreichen?
Bisher mache ich das so, aber es funktioniert nicht:
import sys
sys.path.append(".")
from B import test
Nun erhalte ich den folgenden Fehler:
ImportError: No module named 'data'
Vielen Dank für die Hilfe!
-
- User
- Beiträge: 1715
- Registriert: Freitag 31. Juli 2015, 13:34
Komisch, dass ich das bisher immer in Python3 gebraucht hatte. Vielleicht braucht man es ja mit python 3.6 nicht mehr?Sirius3 hat geschrieben:@Alfons Mittelmeyer: __init__.py ist bei Python 3 nicht mehr nötig.
@ewkos: Du musst in Deinen Unterverzeichnissen eine leere Datei namens __init__.py anlegen!
Ok, vielleicht hätte ich für das Beispiel den Hauptordner anders bennen sollen; Ziel ist es schon, dass main.py in Ordner A ausgefüht werden soll und test.py in Ordner B liegt, welcher auf der gleichen Ebene wie Ordner A ist.
@Ewkos: sauber ist es, wenn die zu importierenden Module im Python-Path zu finden sind, bzw. sich im gleichen Verzeichnis oder in Unterverzeichnissen der Position des Hauptprogramms befinden und dabei nicht mit Packages der Standard Library namentlich kollidieren. Dies lässt sich umgehen, wie ich in einem Beispiel gezeigt habe. Das kann man machen, aber es eröffnet die Möglichkeit zu neuen Problemen.