Übergabe von Argumenten an Klasse

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
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

Hallo zusammen,

ich bin relativ neu, was Python angeht und gerade dabei, alle möglichen Sortieralgorithmen als Übung in Python umzusetzen. Hierzu erstelle ich mir jeweils eine eigene Klasse per Algorithmus.

Momentan hab ich die Klasse so gestaltet, dass ich im Constructor default-Werte definiert habe und in der Methode erst die konkreten Argumente übergebe. Ist das good practice unter Python oder übergebe ich die Argumente direkt im Constructor und übergebe dann die self.args an die Methode?

Vielen Dank und viele Grüße
Marvin

Hier die Klasse:

Code: Alles auswählen

class BubbleSort:
    def __init__(self, array=None):
        self.array = array

    def start(self, array):
        self.array = array

        n = len(self.array)

        for j in range(1, n):
            for i in range(0, n - j):
                if self.array[i] > self.array[i + 1]:
                    temp = self.array[i]
                    self.array[i] = self.array[i + 1]
                    self.array[i + 1] = temp

            print(self.array)

        return self.array


## Testen
A = [2, 5, 6, 4, 1, 3, 5, 2, 8]
bubble = BubbleSort()
print(bubble.array) # -> ergibt None (Default)
print(bubble.start(A)) # -> ergibt das sortierte übergebene Array
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Best practice in Python ist, einfach keine Klasse als Container zu verwenden. Hier ist eine Klasse unnötig. Es reicht eine einfach Funktion. Die Klasse hat bietet keinen Mehrwert - außer dass man sich fragt, wo welche Argumente definiert werden.
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

Hallo Sparrow (Käpt'n? ;-) ),

danke für deine Antwort.

Ich weiß, dass es wahrscheinlich unlogisch erscheint, dafür eine eigene Klasse zu erstellen, aber ich möchte gerne mehrere Klassen in meiner Main-Datei nutzen, statt mehrerer Funktionen untereinander. Also die Funktionen in Klassen auslagern quasi...

Die Frage, wo welche Argumente definiert werden, stellt sich mir ja schon :) Jetzt mal abgesehen davon, ob es Sinn macht, das in Klassen auszulagern oder nicht: gibt es in Python so ne Art best practice, an welcher Stelle man die konkreten Argumente übergibt oder defaults?

Viele Grüße
Marvin
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Das ändert nichts an meiner Antwort.
Was du tust ist Java, nicht Python.
Du kannst versuchen gegen die Programmiersprache zu programmieren. Das ist allerdings zum Scheitern verurteilt.
Du willst Klassen als Container verwenden. Und das ist schlicht falsch. Deshalb stellt sich die Frage gar nicht, die du beantwortet haben möchtest.
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

Du willst Klassen als Container verwenden.
Sorry, aber das hab ich nicht so ganz verstanden, was du damit meinst :?

Ist Python absolut gar nicht für ein wenig Objektorientierung geeignet? :oops:

Viele Grüße
Marvin
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

Nehmen wir Mal ein anderes Beispiel:

Ich möchte das Objekt "Auto" erzeugen und habe hierzu eine Klasse. Übergebe ich die Parameter des Autos im Constructor der Klasse oder in der Klassenmethode "baueauto"?

Viele Grüße
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Doch, warum nicht?
Was hat das eine mit dem anderen zu tun?
Alles in Pyhon ist ein Objekt.

Aber das hat nichts mit deinem Anliegen zu tun. Du möchtest ja gar kein Objekt durch eine Klasse darstellen. Was für ein Objekt soll das denn sein?
Objektorientierte Programmierung braucht man dann, wenn man Werte in einem Objekt über eine Funktion hinaus ehalten möchte. Das ist bei dir definitiv nicht der Fall.

Ein guter Ansatz: Wenn man "self" nicht braucht, ist es kein Objekt.
Du brauchst self nicht, wie man an deinem Code weiter oben sieht.
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

zur "Auto"-Klasse:
Da fehlen grundlegende Informationen und Kontext. Grundsätzlich gilt - und das nicht nur in Python: Alles was das Objekt braucht, um erstellt zu werden, benötigt es natürlich bei Erstellung.
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

Alles was das Objekt braucht, um erstellt zu werden, benötigt es natürlich bei Erstellung.
Das ist mir bewusst. Daher die Frage, ob ich die defaults definiere oder direkt die konkreten Parameter übergebe.

Aber ich glaub wir drehen uns gerade etwas im Kreis :lol: und vielleicht bin ich tatsächlich zu sehr "Java-geschädigt".
Werd jetzt "nur" die Methoden in eigene Module auslagern, damit meine main nicht so viele Zeilen Code hat. :)

Trotzdem vielen Dank für deine Antworten!

Viele Grüße
Marvin
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Unabhängig davon, dass in Deinem Beispiel eine Klasse Unsinn ist, falls Du eine wirkliche Klasse hättest, dann sollte der Aufruf von __init__ die Klasse in einen Zustand versetzen, dass sie fertig benutzbar ist. Das was in einer Methode `baueauto` passiert, kann genausogut in __init__ stehen.
Grundsätzlich kannst Du auch eine classmethod `baueauto` definieren, die noch mehr macht, aber die ruft zum Schluß __init__ auf und initialisiert damit die Klasse.

Zu Deinem Code: was Du `array` nennst, ist eine Liste, und Typen sollten sowieso nicht in Variablennamen vorkommen. Typischerweise würde man die Variable `values` nennen. Konvention ist, dass Funktionen, die eine Liste verändern, diese nicht als Rückgabewert haben, siehe list.sort:

Code: Alles auswählen

def bubble_sort(values):
    n = len(values)
    for j in range(1, n):
        for i in range(0, n - j):
            if values[i] > values[i + 1]:
                values[i], values[i + 1] = values[i + 1], values[i]
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

was Du `array` nennst, ist eine Liste
Oh, du hast natürlich Recht, es ist eine Liste!
und Typen sollten sowieso nicht in Variablennamen vorkommen. Typischerweise würde man die Variable `values` nennen.
Alles klar! :)
Konvention ist, dass Funktionen, die eine Liste verändern, diese nicht als Rückgabewert haben, siehe list.sort:
Okay, das wusste ich noch nicht. Ich dachte ich kann mir nach dem Sortieren die Liste wieder zurückgeben lassen.

Ich merk schon, meine Programmierkenntnisse - insbesondere in Python - sind echt schlecht. Noch... aber es macht Spaß! :)

Wünsche euch beiden einen schönen Rest-Freitag und hoffentlich sturmfreies Wochenende.

Viele Grüße
Marvin
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@elmarvo: Wenn ich das richtig verstanden habe willst Du jetzt statt die Funktionen in jeweils eine eigene Klasse zu stecken, nun die Funktionen jeweils in ein Modul stecken — warum dass denn bitte? Auch das macht so als Selbstzweck erst einmal gar keinen Sinn. Oder hattest Du etwas vorher auch ein Modul pro Klasse? Das wäre auch ”falsch”. Python ist nicht Java. Module sind dazu da zusammengehörende Funktionen und Klassen in einem Namensraum zusammenzufassen. Also das was Packages in Java sind. Du steckst dort ja auch nicht jede Klasse einzeln in ein eigenes Package. Dort würde man ja ein Package für Sortieralgorithmen anlegen und dann dort die Klassen für Bubblesort, Quicksort, etc. rein packen, und nicht ein Package für Sortieralgorithmen wo dann für jeden Algorithmus ein Package liegen würde, wo dann jeweils genau eine Klasse drin stehen würde. Mach das nicht komplexer als es sein muss. Diesen Impuls haben Java-Programmierer manchmal — kämpf dagegen an. (Auch bei Java!). KISS & YAGNI. 🤓

Die gezeigte BubbleSort-Klasse wäre übrigens auch in Java so unsinnig/falsch. Auch dort würde man das Array/die Sequenz nicht als Zustand haben, sondern eine statische `sort()`-Methode definieren. Also letztlich eine Funktion. Muss halt in Java in einer Klasse stecken weil es dort nicht anders geht. Ginge es, würde man es dort auch anders machen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@elmarvo: Das, was du da machen willst, hat nichts mit Objektorientierung zu tun, sondern nur mit den sonderbaren Ansichten, die Java darüber hat. Eine Sprache ist IMO objektorientiert, wenn alles ein Objekt ist. Methoden, Klassen und Module sind in Java keine Objekte, in Python schon. Und objektorientiert heißt auch nicht, dass es Klassen geben muss. Da gibt es zB. objektorientierte Sprachen wie Self, das keine Klassen kennt, sondern nur Prototypen und Traits. Und objektorientiert heißt erst recht nicht, dass jede Funktion als Methode einer Klasse definiert werden muss.

Im Übrigen - vergleich das mal mit deiner Lösung:

Code: Alles auswählen

def bubblesort(items):
    n = len(items)
    for j in range(1, n):
        for i in range(0, n - j):
            if items[i] > items[i + 1]:
                items[i], items[i + 1] = items[i + 1], items[i]
        print(items)
    return items
Ungetestet.

PS: Listen sind keine Arrays. Wenn man in Python von Arrays spricht, meint man damit in 99.32% der Fälle numpy Arrays.
In specifications, Murphy's Law supersedes Ohm's.
elmarvo
User
Beiträge: 11
Registriert: Freitag 18. Februar 2022, 09:57

@alle: danke für das Feedback und die konstruktive Kritik, die mich teilweise auch zum Schmunzeln gebracht hat! :)

Ich denke, ich sollte wohl erstmal das offizielle Python-Tutorial büffeln :D

Ihr seid eine tolle Community hier! :)

Bis bald
Marvin
Antworten