@AtomicOne: Sternchen-Importe sind Böse™. Nicht machen! Da holt man sich alle Namen aus einem Modul in den Namensraum des importierenden Moduls. Nicht nur die Namen die dort definiert wurden sondern auch die Namen die das Modul selbst wieder von irgendwo anders importiert hat. Dann kann man sich Namensräume auch gleich sparen. Man sollte an den Importen sehen können was woher kommt.
Es funktioniert alles Mögliche. Python ist da ja sowieso recht flexibel und verbietet kaum etwas. Um so mehr wird aber auf Konventionen Wert gelegt. Um sauberen, leicht verständlichen Code zu schreiben. Und deswegen die Ordnung bei Importen und nur ein Modul pro Import-Anweisung. Damit man den Überblick nicht verliert, alles ordentlich sortiert ist, man nichts mehrfach importiert, und auch nicht verwendete Importe leichter erkennen und beseitigen kann.
Wenn man einen trivialen Getter und Setter für ein Attribut hat dann ist das doch überhaupt gar nicht gekapselt, denn es macht Null unterschied ob das über triviale Getter/Setter oder einfach als Attribut verfügbar ist. Ansonsten kapselt man in dem man halt nicht auf Sachen zugreift auf die nicht zugegriffen werden sollte. Wie gesagt ist ein führender Unterstrich die Konvention um nicht-öffentliche Attribute zu kennzeichnen. Kapselung ist nicht gleichbedeutend mit Zugriffsschutz. Der ist (in anderen Programmiersprachen) nur dazu da um die Kapselung gegen Leute durchzusetzen die sie durchbrechen wollen. In Python geht man vom mündigen Programmierer aus, der das nicht macht weil er weiss, dass das keine gute Idee ist, nicht weil die Sprache ihm auf die Finger haut wenn er es macht.
Ganz wichtig: Vergiss ``private`` und doppelte führende Unterstriche. Wenn Du das willst, dann willst Du nicht wirklich in Python programmieren und schreibst am Ende furchtbar viel unsinnigen Boilerplate-Code.
Bezüglich Geschmackssache: Es gibt in Python einige Konventionen die wirklich ernst genommen werden. Zum Beispiel das mit dem Tab: Nette Erklärung, dass das in Deinem Editor sonst nicht passiert — aber wenn das hier im Forum im gezeigten Code keine vier Leerzeichen pro Ebene sind, dann wird Dir das von so ziemlich jedem Regular gesagt. Und das auch jedes mal. Namenschreibweisen und das auf Modulebene nur Code gehört der Konstanten, Funktionen, und Klassen definiert ist auch in Stein gemeisselt.
Wie man Importe sortiert ist auch nicht wirklich Geschmackssache wenn das a) übersichtlich sein soll, b) importierte Namen schnell und leicht zu finden sein sollen, c) diffs bei Änderungen möglichst klein sein und möglichst nur die tatsächliche Änderung enthalten sollen, d) bei statischer Analyse die Zeile mit der Markierung möglichst wenige Fehler/Warnungen enthalten soll. Und da hat sich halt die beschriebene Gruppierung/Sortierung durchgesetzt.
Ich schrob `property()` weil es eine Funktion ist und ich die immer mit Klammern versehe, um das deutlich zu machen. Das was Du bei ``@property`` verwendest ist ja auch genau die Funktion, da aber dann mit der Dekorator-Syntax verwendet. Das ist letzlich ”nur” syntaktischer Zucker für folgendes:
Code: Alles auswählen
@decorator
def function(...):
...
# <=>
def function(...):
...
function = decorator(function)
Für ``decorator`` kann da ein beliebiger Ausdruck stehen der zu etwas aufrufbaren ausgewertet wird das *ein* Argument erwartet. Und anstelle von ``def function(...):`` kann da auch ``class Class(...):`` stehen. `property()` gab es schon länger und die Dekorator-Syntax wurde eingeführt, damit man das gleich am Anfang der Funktion/Methode/Klasse sehen kann was da passiert, und nicht erst nach dem Funktion-/Methoden-/Klassenkörper. Der kann ja recht lang sein, und da ist das eventuell etwas überraschend, dass danach noch mal etwas mit dem Objekt gemacht wird und es ersetzt wird durch das Ergebnis des Aufrufs vom Ergebnis von ``decorator``.
Ja, es ist religiös. Die Klammerfrage gibt es in Python nicht. Da gibt es eigentlich nur das Blöcke die nur aus einer Zeile bestehen trotzdem eingerückt auf eine eigene Zeile kommen. Aber mit literalen `True`/`False`-Werten vergleicht man nicht. Auch das wird Dir jedes mal gesagt werden.
Und das `booleanVariable` in Python `boolean_variable` geschrieben wird.
Das Schlüsselwort ``function`` gibt's in Java nicht und Typen sind da im Beispiel auch nicht deklariert. Oder habe ich da etwas verpasst. Zudem funktioniert ``import`` in Java auch deutlich ähnlicher zu dem in Python im Vergleich zu Sprachen wo das eher ein kopieren von Quelltext oder Code an die importierende Stelle ist.
Das `add()` schreibt man in Python übrigens so: ``from operator import add``. Die ganzen Operatoren gibt es als Funktionen in der Standardbibliothek.
Um noch mal auf eine Klasse pro Datei zu sprechen zu kommen: Eine Datei ist in Python ein Modul. Und ein Modul ist ein Namensraum. Namensräume sind dazu da um Namen für zusammengehörende Dinge/Werte/Objekte zusammen zu fassen. Wenn man also in der Regel jeden Namensraum dazu verwendet um genau einen Namen zu definieren, dann ist das objektiv *falsch*. Das heisst nicht, dass man nicht auch mal bei einer sinnvollen, logischen Aufteilung nur eine Klasse in einem Modul haben kann, aber das ist halt nicht die Regel. In Java wäre das beispielsweise so als würde man in jedem Package genau eine Klasse ablegen, also immer nur eine Klasse pro Verzeichnis. Da wird auch jeder Java-Programmierer sagen das ist falsch, auch wenn man das natürlich machen kann und es funktioniert.