Packages richtig importieren

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
rainu
User
Beiträge: 3
Registriert: Samstag 4. Juni 2011, 19:35

Hallo zusammen,
ich komme aus der java-welt und organisiere da meine software-projekte in packages. Das selbe habe ich jetzt auch in meinem ersten python-projekt vor. Dabei lege ich auch für jede Klasse eine extra datei an. Ich verwende die entwicklungsumgebung eclipse und habe dessen "vorschläge" verwendet, die in etwa so aussehen:

Code: Alles auswählen

from de.rainu.prject.test import TestClass
Nun haben sich aber ab und zu probleme eingenistet, da ein paar datein untereinander die selben klassen-dateien als abhängigkeit importieren. Soweit ich mich errinern kann, bedeutet ja das "from ... import..." eine kopierung.

Bevor ich jetzt mein projekt weiter wachsen lasse, möchte ich sichergehen, dass ich wenigstens richtig importiere um mich nur mit "richtigen" fehlern herumschlagen muss. Wie würdet ihr größere projekte organisieren?

MfG Rainu
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

rainu hat geschrieben:Das selbe habe ich jetzt auch in meinem ersten python-projekt vor. Dabei lege ich auch für jede Klasse eine extra datei an.
Wozu das? In Python ist das so nicht notwendig und auch nicht so vorgesehen. Inhaltlich zusammengehörige Dinge kannst Du in eine Datei (und damit ein Modul) packen.
rainu hat geschrieben: Ich verwende die entwicklungsumgebung eclipse und habe dessen "vorschläge" verwendet, die in etwa so aussehen:

Code: Alles auswählen

from de.rainu.prject.test import TestClass
Nun haben sich aber ab und zu probleme eingenistet, da ein paar datein untereinander die selben klassen-dateien als abhängigkeit importieren.
Welche Probleme denn im speziellen?
rainu hat geschrieben: Soweit ich mich errinern kann, bedeutet ja das "from ... import..." eine kopierung.
"Kopierung" als Wort empfinde ich als unschön - gibt es das überhaupt? Davon abgesehen kapiere ich nicht, was Du damit meinst.

Hast Du mal im Tutorial den Abschnitt über Module und Pakete durchgelesen?
rainu hat geschrieben: Bevor ich jetzt mein projekt weiter wachsen lasse, möchte ich sichergehen, dass ich wenigstens richtig importiere um mich nur mit "richtigen" fehlern herumschlagen muss. Wie würdet ihr größere projekte organisieren?
Ich würde mir mal größere Projekte angucken, z.B. Django, SQLAlchemy, lxml, Werkzeug, etc. und dort gucken, wie die ihren Code organisieren. An solchen Erfolgsmodellen kann man sicherlich am besten lernen, wie so etwas gut gemacht wird. Naheliegend kannst Du Dir ja auch mal die Standard-Lib angucken; da erkennst Du ja auch schön, wie die Module organisiert sind.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@rainu: Ich weiss jetzt nicht was Du mit ”eine kopierung” meinst, aber Werte, also Objekte, werden von Python nicht implizit kopiert. So ein ``from``-Import bedeutet, das die Objekte aus dem Modul die man explizit angibt, im importierenden Modul an die angegebenen Namen gebunden werden.

Die Java-Gewohnheiten einfach 1:1 zu übernehmen ist keine gute Idee. Python ist nicht Java. Module sind dazu gedacht, mehrere, zusammengehörige Funktionen und Klassen zu bündeln. Und nicht um in jedes Modul nur eine Klasse zu stecken. Dann hätte man sich das Modul als Organisationseinheit ja auch sparen können. Packages sind dazu da mehrere Module oder Unter-Packages zu bündeln. Wobei ein Package durch die `__init__.py` auch immer gleichzeitig einen Modulnamensraum bereit stellt. Dadurch kann man zum Beispiel auch auch aus einem Modul das mit der Zeit wächst, ein Package machen, ohne das sich dadurch sofort die API ändert.

Im Python-Zen, was man zum Beispiel durch ``import this`` einsehen kann, steht unter anderem „Flat is better than nested”. Schau Dir mal die Modul- und Pakethierarchie von der Standardbibliothek und verbreiteten Python-Bibliotheken an. Was Du da vorhast ist ziemlich ”unpythonisch”
rainu
User
Beiträge: 3
Registriert: Samstag 4. Juni 2011, 19:35

Hyperion hat geschrieben: Wozu das? In Python ist das so nicht notwendig und auch nicht so vorgesehen. Inhaltlich zusammengehörige Dinge kannst Du in eine Datei (und damit ein Modul) packen.
Nehmen wir mal an wir haben "nur" 3 classen die jewiels 300zeilen code haben das macht dann die datei (für mich) ziemlich unübersichtlich.
Hyperion hat geschrieben: "Kopierung" als Wort empfinde ich als unschön - gibt es das überhaupt? Davon abgesehen kapiere ich nicht, was Du damit meinst.
Damit meine ich, wenn man from, verwendet werden die datei inhalte kopiert und nich wie beimimport vw'erwiesen (so ungefähr^^)

Edit: ich lass ,ich gern hinreisen um keine packages zu verwenden (mach ich in c++ ja auch nich) aber ich hab bedenke alle "zusammengehörige" klassen in ein modul zu schreiben. Denn da komm ich ganz schnell in die 1500+zeilen code die das ganze ziemlich unübersichtlich machen.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

rainu hat geschrieben: Damit meine ich, wenn man from, verwendet werden die datei inhalte kopiert und nich wie beimimport vw'erwiesen (so ungefähr^^)
Kapiere ich immer noch nicht. Aber BlackJack hatte da wohl den richtigen Riecher.
rainu hat geschrieben: Edit: ich lass ,ich gern hinreisen um keine packages zu verwenden (mach ich in c++ ja auch nich) aber ich hab bedenke alle "zusammengehörige" klassen in ein modul zu schreiben. Denn da komm ich ganz schnell in die 1500+zeilen code die das ganze ziemlich unübersichtlich machen.
Naja, dafür gibt es ja bei so komplexen Sachen eine hoffentlich vorhandene Doku. Zudem sollte man schon einen Editor (IDE) verwenden, die einem gewissen Komfort bietet (Klassen-, Methoden-, Funktionslisten, usw).

Wenn Du aus der Java-Ecke kommst und Eclipse verwendest (gilt sicher für alle Java IDEs), dann spielen die Anzahl an Dateien doch für Dich eigentlich keine Rolle mehr. Ja man könnte so weit gehen uns sagen, dass die physische Datei an sich fast schon nicht mehr unmittelbar interessant und damit für den Entwickler präsent sind. Ich habe mich da immer auf den Package-Explorer verlassen und Klassen und Methode darüber angesteuert, zudem die Quicklink-Funktion genutzt. Wenn Java die Klassen also in eine Datei schriebe, so würdest Du das gar nicht mehr mitbekommen geschweige Dich daran stören. Insofern halte Dich an den von BlackJack beschriebenen Pythonischen Weg; damit fährst Du einfach besser in Python.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@rainu: Wie gesagt: Beim Import wird nichts kopiert — es werden nur Namen im lokalen Modul an Objekte aus dem importierten Modul gebunden.

Was die Anzahl der Codezeilen angeht, solltest Du bedenken, dass Du nicht so einfach die Erfahrung von Java auf Python übertragen kannst. Python-Quelltext ist oftmals kürzer als das was man in Java dafür schreiben müsste. Man bekommt in 1.000 Zeilen Python-Quelltext also in der Regel mehr Funktionalität untergebracht als bei 1.000 Zeilen Java-Quelltext.
rainu
User
Beiträge: 3
Registriert: Samstag 4. Juni 2011, 19:35

BlackJack hat geschrieben:Was die Anzahl der Codezeilen angeht, solltest Du bedenken, dass Du nicht so einfach die Erfahrung von Java auf Python übertragen kannst. Python-Quelltext ist oftmals kürzer als das was man in Java dafür schreiben müsste. Man bekommt in 1.000 Zeilen Python-Quelltext also in der Regel mehr Funktionalität untergebracht als bei 1.000 Zeilen Java-Quelltext.

Das mag sein dazu bräuchte man denke ich mehr erfahrung on der sprache. Da das dennoch mein erstes python projekt ist, gilt dies quasi als meine python übung und warscheinlich am ende des projekte bin ich so erfahren, dass ich das meiste hätte kleiner machen können (wie das eben so ist -> nach der ersten programmierung möchte man meist alles nochmal schreiben)
LivingOn
User
Beiträge: 33
Registriert: Montag 11. August 2008, 07:53

BlackJack hat geschrieben:@rainu: Wie gesagt: Beim Import wird nichts kopiert — es werden nur Namen im lokalen Modul an Objekte aus dem importierten Modul gebunden.
Mit Hilfe von "from ... import ..." werden Objekte aus importierten Modulen an den lokalen Namensraum gebunden.
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Klassen mit 300 Zeilen Code klingen für mich aber doch schon nach schlechtem Design, ehrlich gesagt.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Faustformel: eine normale Methode sollte nicht mehr als 7 Zeilen Code haben - eher weniger. Eine Klasse sollte nicht mehr als 49 (damit wir bei der 7 bleiben) Methoden haben und eine Klasse damit nicht mehr als 343 Zeilen. Eine Initialisierung mag davon mal abweichen, aber immer wenn man den Wunsch spürt, mal in einer Methode einen Codeabschnitt zu dokumentieren, ist das ein Zeichen dafür, dass das eine neue Methode oder Hilfsfunktion ist.

Stefan
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Keine Ahnung, ob ich der einzige bin, aber 49 Methoden für eine Klasse finde ich schon arg viel. Also insgesamt eine solche Anzahl aufgrund von Vererbungen zu haben, ist etwas anderes. Ich glaube, ich würde sowas aufteilen wollen, eben *weil* damit die Übersicht verloren geht. Wenn man dann mehrere Klassen hat, kann man die entsprechend auch zusammen in ein Modul packen. Also so, wie es der OP gemacht hat, nur dass der Code halt geplittet wird.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

snafu hat geschrieben:Keine Ahnung, ob ich der einzige bin, aber 49 Methoden für eine Klasse finde ich schon arg viel.
Das war einfach mal eine Zahl und ist definitiv eine Obergrenze, die man nicht einhalten muss. Für Java kann ich's auf die Schnelle nicht sagen, aber ein jungfräuliches Pharo-Smalltalk-System hat 6179 Klassen. Die Klasse Object hat 361 Methoden. Gemittelt über alle Klassen sind das dann etwa 9 Methoden pro Klasse. Ignoriert man mal die vielen Klassen, die gar keine Methoden haben (1917), steigt der Durchschnitt auf 14. Immerhin gibt es aber 215 Klassen, die mehr als 49 Methoden haben. Ich glaube, den Vogel schießt die Klasse Morph (Oberklasse für alle UI-Elemente) mit 895 Methoden ab - das habe ich aber auch schon vor 10 Jahren für schlechtes Design gehalten.

Bei Ruby hat z.B. Array 84, Hash 47 und String 92 eigene Methoden. Object selbst hat keine, erbt aber insgesamt 45, die dann noch zu den eigenen von Array, Hash usw. kommen. Dazu kommen noch Mixins wie z.B. Enumerable, welches z.B. 44 mitbringt.

Während eigene Klassen eigentlich nie so viele Methoden haben sollten, können wiederverwendbare Klassen der Standardbibliothek durchaus mal die 49 erreichen oder sogar überschreiten. Um so wichtiger eigentlich, dass man Klassen nochmals, z.B. mit Hilfe von Traits oder Mixins unterteilen sollte.

Stefan
Antworten