Kreuzweises Importieren 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
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

Hallo.

Ich habe folgende zwei Beispielscripte:

Code: Alles auswählen

### eins.py
from zwei import C

class A:
    def __init__(self):
        C()

class B:
    pass



### zwei.py
from eins import B

class C (B):
    pass
So geht das ganze schonmal nicht:

Code: Alles auswählen

Traceback (most recent call last):
  File "eins.py", line 1, in <module>
    from zwei import C
  File "/home/cui/projects/bjs-prog/zwei.py", line 1, in <module>
    from eins import B
  File "/home/cui/projects/bjs-prog/eins.py", line 1, in <module>
    from zwei import C
ImportError: cannot import name C
Wenn ich jetz in zwei.py den import auskommentiere dann gehts aber auch nicht:

Code: Alles auswählen

Traceback (most recent call last):
  File "eins.py", line 1, in <module>
    from zwei import C
  File "/home/cui/projects/bjs-prog/zwei.py", line 3, in <module>
    class C (B):
NameError: name 'B' is not defined
Was soll ich jetzt tun?

lg,
cui.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hallo cui, willkommen im Forum,

Steck die Klassen doch einfach in ein Modul.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
BlackJack

@cui: Du solltest einfach keine Module mit gegenseitigen Abhängigkeiten schreiben. Entweder ist das ein Zeichen, dass alles in ein Modul gehört, oder Du solltest Sachen, die beide Module benötigen, in ein drittes Modul auslagern.
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

Ok, aber es ist doch auch ein schlechter Stil, meinetwegen 10 Klassen alle in eine Datei zu schreiben... Also ich jedenfalls finds unübersichtlich.. Außerdem wird die Arbeit als Team deutlich erschwert wenn alles in einer Datei liegt...

Oder gibt es eine Möglichkeit, ein Modul in mehrere Dateien auf zu spalten?
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Datei = Modul.

Nein, es ist kein schlechter Stil zusammenzupacken, was zusammengehört.

Wie wird denn die Teamarbeit behindert? Im Zeitalter von Versionskontrollen und Diff-/Mergetools kann das doch nicht dein ernst sein?
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

Ok, es handelt sich um eine kleines Schülerprojekt, und außer mir und vllt noch 1 oder 2 hat da keiner eine Ahnung was Bazaar oder Subversion ist. Python dagegen wurde sehr wohl behandelt.

Abgesehen davon:
Ich persönlich jedenfalls finde eine Datei mit sagen wir 2000 Zeilen Code (es sind genau 7 Klassen die untereinander referenzieren) unübersichtlich.. Ich weiß nicht wies euch geht.

In anderen modernen Hochsprachen wie Java, C# ist derartig triviales wie Strukturierung nach Klassen doch auch möglich und vorallem normal..
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Dann nehmt euch die 10 Minuten die es braucht sich mit Mercurial bekannt zu machen, geht zu bitbucket.org und die Zusammenarbeit ist kein Problem.

Mercurial lässt sich natürlich mit jeder anderen (D)VCS-Software austauschen und bitbucket.org mit jedem anderen Hoster.

Wenn ihr so große Implementationen mit so großen Abhängigkeiten habt und ihr es selbst als übersichtlich empfindet, solltet ihr euch mal den Code genauer anschauen und überarbeiten.
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

Na ja, wenn du die Tabelle für das Deutsche Sportabzeichen abtippen musst (mit welchen Weiten man besteht wenn man z.B. 15 Jahre und meinetwegen männlich ist), dann sind das shcon alleine mind. 300 Zeilen trivialer Code...
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das sind aber 300 Zeilen Code, die eigentlich kein Code sind, sondern Daten.
Da bietet sich das CSV-Modul an.

Und wenn man das fest in ein Programm verdrahtet ist das durchaus schlechter Stil ;)
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

Da stimme ich dir prinzipiell zu, es wäre vielleicht am Klügsten gewesen. Aber nun steht es leider aufgrund meines Planungsfehlers schon so da und ich habe keine Lust eigentlich mir die Arbeit mit dem Abschreiben nochmal zu machen.
... Wenn du die Tabelle nochmal abschreiben willst und einen Parser dafür, bitte gerne, wir wären dir dankbar!

Sagen wir einfach das Projekt steht bereits zur Hälfte, und nochmal alles um zu designen wäre uns zu viel Aufwand. Nächstes mal planen wir das dann besser, da wir nun ja wissen, dass sich referenzierende Klassen in Python schnell zu Schwierigkeiten führen können; das hatte ich einfach nicht bedacht beim Entwurf, mein Fehler.

Also um zur Frage zurück zu kommen: Gibt es nun irgendeine andere Möglichkeit, als alles in eine Datei zu packen, oder müssen wir selber schaun wie wir nun damit umgehen?

lg,
cui
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

7 Klassen und 2000 Zeilen? Hört sich nach viel an... vielleicht macht ihr euch das Leben auch schwerer, weil ihr versucht in Python wie in einer gewissen "modernen Hochsprache" zu programmieren, die ich jetzt mal ungenannt lassen will ;)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

birkenfeld hat geschrieben:7 Klassen und 2000 Zeilen? Hört sich nach viel an... vielleicht macht ihr euch das Leben auch schwerer, weil ihr versucht in Python wie in einer gewissen "modernen Hochsprache" zu programmieren, die ich jetzt mal ungenannt lassen will ;)
Bitte fang jetzt nicht an über Programmiersprachen zu diskutieren!
Ich habe bisher vorallem Ruby und Java, aber auch Python, C# und Haskell programmiert.
Python war Vorgabe, weil es alle konnten.

PS: mit "modern" war "modern im Vergleich zu C" gemeint, nicht "modern im Vergleich zum Rückständigen Python". Versteh mich nicht falsch, ich mag Python eigentlich, ich habe damit programmieren gelernt und find es immer noch eine sehr schöne Sprache!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Die Alternative ist eben eine dritte Datei zu verwenden.

Aber das löst ja das eigentlich Problem nicht, denn das ist das schlechte Design und das ist durchaus teurer was Wartbarkeit und Erweiterbarkeit angeht als die Probleme zu lösen.

Für CSV braucht es keinen besonderen Parser, das bringt Python schon mit. Das Verarbeiten ist aber euer Bier, vielleicht gibt es auch eine gut maschinenlesbare Version, die man einfach automatisch abernten kann.

Was birkenfeld meint ist, dass ihr nicht in Python sondern in der Programmiersprache mit dem `J` schreibt, die dazu neigt alles komplizierter zu machen als es zu sein braucht ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

cui hat geschrieben:Bitte fang jetzt nicht an über Programmiersprachen zu diskutieren!
Ich habe bisher vorallem Ruby und Java, aber auch Python, C# und Haskell programmiert.
Python war Vorgabe, weil es alle konnten.
Ich denke birkenfeld wollte eher darauf hinweisen dass 7 Klassen die 2000 Zeilen haben und in einem Modul stehen weil sie sich selbst gegenseitig referenzieren nach einem "Code Smell" klingen. Und 1 Datei pro Klasse macht die Sache eigentlich auch nicht übersichtlicher. Gute Trennung macht Dinge übersichtlicher, aber sowas kann man natürlich auf Syntaxebene nicht erzwingen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

cui hat geschrieben:
birkenfeld hat geschrieben:7 Klassen und 2000 Zeilen? Hört sich nach viel an... vielleicht macht ihr euch das Leben auch schwerer, weil ihr versucht in Python wie in einer gewissen "modernen Hochsprache" zu programmieren, die ich jetzt mal ungenannt lassen will ;)
Bitte fang jetzt nicht an über Programmiersprachen zu diskutieren!
Uh, das ist hier immer noch ein Forum... Aber ich wollte sowieso nicht auf eine Sprachendiskussion hinaus.
PS: mit "modern" war "modern im Vergleich zu C" gemeint, nicht "modern im Vergleich zum Rückständigen Python". Versteh mich nicht falsch, ich mag Python eigentlich, ich habe damit programmieren gelernt und find es immer noch eine sehr schöne Sprache!
Das bezweifle ich ja gar nicht :)

Um noch ein bisschen "produktiveres" beizutragen: zum einen würde es mich nicht mal sonderlich stören, wenn das eine Modul 2000 Zeilen hat, wenn diese *wirklich* eine Einheit bilden, die auseinanderzunehmen noch verwirrender wäre. Allerdings ist es auch möglich, dass sich eine natürliche Aufteilung ergibt, die sich euch einfach noch nicht angeboten hat.

Dann gibts immer noch die Möglichkeit, Imports lokal in Funktionen zu packen, womit man eigentlich wirklich notwendige zirkuläre Abhängigkeiten erschlägt:

Code: Alles auswählen

# eins.py
class A:
     def __init__(self):
          from zwei import C
          self.whatever = C()
class B:
    pass
# zwei.py
from eins import B
class C(B):
    pass
Trotzdem gibt es normalerweise eine Möglichkeit, gemeinsame "Vorfahren" (hier B) in ein weiteres Modul auszulagern, und so zirkuläre Module zu vermeiden.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
cui
User
Beiträge: 7
Registriert: Montag 22. Juni 2009, 21:28

cofi hat geschrieben:Was birkenfeld meint ist, dass ihr nicht in Python sondern in der Programmiersprache mit dem `J` schreibt, die dazu neigt alles komplizierter zu machen als es zu sein braucht ;)
Ich stimme euch da doch zu.
Denn was ich meinte ist, das mit das wohl bewusst ist, dass ich aber auch Sprachen gut kenne, in denen Dinge anders laufen.. ;)

Aber ich merke, letzlich war es ja wohl ich, der eine solche Diskussion losgetreten hat, darum möchte ich jetzt eigentlich nur noch allen für die schnellen Antworten danken, die ihr mir gegeben habt.

lg,
cui.

EDIT: @birkenfeld: Danke vorallem für deine Antwort grade eben. Das mit den lokalen Imports war mir neu. Und das mit dem Auslagern dieser Klasse ist mir im Laufe der Diskussion auch gekommen solangsam.. ich glaube dann müsste es funktionieren ohne zirkuläre Abhängigkeiten und ohne groß das Konzept zu ändern ;)
BlackJack

@cui: Wie (un)übersichtlich so etwas wird, ist auch immer eine Frage der Werkzeuge. Ob die Klassen bei Java in Einzeldateien oder alle in Einer stehen, wäre mir zum Beispiel völlig egal, weil die typische Java-IDE Baumansichten von den Klassen bereitstellt, wo ich nur auf die Klasse oder Methode klicken muss und dann im Quelltext dort hin springe. Es gibt Python-IDEs die das auch bieten. Aber selbst ein einfacher Editor mit "code folding" schafft es sieben Klassen in einem Editorfenster gleichzeitig sichtbar zu machen.

Wenn Du die Tabellen schon als Code eingetippt hast, sollte es doch wohl möglich sein, die in eine Datendatei auszulagern, ohne dass Du sie noch einmal eintippen musst. Entweder durch entsprechendes umarbeiten des Quelltextes oder in dem Du Code schreibst, der die Daten aus dem Programm in eine Datendatei schreibt. Zum schreiben und lesen von CSV-Dateien gibt es in der Standardbibliothek das `csv`-Modul.
Antworten