Seite 1 von 1

Python Klassenvererbung und Werte Initialisierung

Verfasst: Samstag 25. April 2020, 19:47
von m.g.o.d
Hallo Zusammen,

Bisher habe ich in Python immer Funktionen geschrieben und wollte nun mein aktuelles Programm in eine Klassenhierachie übersetzen, quasi auch um das zu üben. Jetzt hab ich irgendwie einen Knoten im Gehirn. Vielleicht könnt ihr mir da weiterhelfen?

Folgendes Programm:

Code: Alles auswählen

import sys, urllib.request

class URL_MASTER():

    def __init__(self, eingabe_url, url, html_home):

        self.eingabe_url = input("Bitte URL eingeben:")
        self.url = urllib.request.urlopen \
                    (self.eingabe_url)  
        self.url.close()
        self.html_home = self.url.readlines()
        self.html_home = str(self.html_home)

class URL_SLAVE(URL_MASTER):

    def __init__(self, eingabe_url, url, html_home, eingabe_query, soup, html_home_sublinks):  

        URL_MASTER.__init__(self, eingabe_url, url, html_home)     
        self.eingabe_query = input("Bitte Suchwort eingeben:")
        self.soup = BeautifulSoup(self.html_home, 'html.parser')
        self.html_home_sublinks = [a['href'] for a in self.soup.find_all('a', href=True) if a.text]
        self.html_home_sublinks = set(self.html_home_sublinks)
        self.html_home_sublinks = list(self.html_home_sublinks)

    def ausgabe(self):
        print(self.html_home)
 
  
# Zugriffsobjekte auf Klasse      
if __name__ == "__main__":
    #TESTOBJEKT1 = URL_MASTER(eingabe_url=[], url=[], html_home=[])
    TESTOBJEKT2 = URL_SLAVE(eingabe_url=[], url=[], html_home=[], eingabe_query=[], soup=[], html_home_sublinks=[])
    TESTOBJEKT.ausgabe()
Mein Problem ist jetzt, wenn ich nur die Basisklasse nehmen und über TESTOBJEKT1 = URL_MASTER(eingabe_url=[], url=[], html_home=[]) aufrufe, dann haben die Variablen alle sinnvolle Werte. Sobald ich an die abgeleitete Klasse URL_SLAVE() gehe, dann werden nur leere Listen [] angezeigt...was irgendwo sogar nachvollziehbar ist.

Ich störe mich aber an der Deklaration BEVOR ich diese eigentlich in der Klasse machen möchte. In den ganzen Tutorials werden oft einfache Zahlen übergeben, das ist alles klar. Aber das hilft mir hier nicht weiter. Der Konstruktor erwartet ja eine definierte Variable...wenn ich einfach nur schreibe:

Code: Alles auswählen

TESTOBJEKT1 = URL_MASTER(eingabe_url, url, html_home)
kommt:

NameError: name 'eingabe_url' is not defined

Aber die Definierung dieser Variable möchte ich ja eigentlich innerhalb der Klasse machen und nicht außerhalb...sonst bräuchte ich keine Klasse und könnte einfach weiterhin Funktionen schreiben.

Außerdem möchte ich von der Basisklasse URL_MASTER() eigentlich auch nur html_home haben und den Rest nicht, aber der Konstruktor von URL_SLAVE() erwartet die gesamte Liste...aber das ist ein Folgeproblem :oops: :oops:

Könnt ihr mir sagen, wo mein Denkfehler ist? Also zusammengefasst:

In der Klasse URL_MASTER() wird der HTML Quellcode der Eingabe (z.B. https://www.python-forum.de/) in die Variable self.html.home eingelesen.

Diese Variable brauche ich dann in der Klasse URL_SLAVE(), wo ich diese Seite nach allen Sublinks (<a.href>) durchsuche und das Ergebnis sortiert in einer Liste speichere. Wie gesagt, geschrieben als Funktion funktioniert das alles prima... :cry:

Re: Python Klassenvererbung und Werte Initialisierung

Verfasst: Samstag 25. April 2020, 20:13
von Sirius3
Variablen schreibt man klein, Klassen mit großen Anfangsbuchstaben. Dass Du alles wie Konstanten schreibst, ist sehr verwirrend. Die vielen falsch geschriebenen Variablen und fehlenden Inputs machen es auch nicht gerade leicht, das was Du willst zu verstehen.
Die Klassen machen so auch keinen Sinn. Ich versteh nicht, warum Du hier Vererbung brauchst. Ein Slave ist ganz selten ein Master.
UrlMaster.__init__ hat als Argument eingabe_url, überschreibt das aber mit dem Rückgabewert von input. Das macht keinen Sinn. input ist auch selten in __init__ sinnvoll, weil so die Klasse felxibel nutzbar ist.
Ebenso sind viele Argumente in UrlSlave.__init__ unsinnig, weil sie nicht benutzt werden.

Wenn es mit Funktionen funktioniert, dann bleib dabei.

Re: Python Klassenvererbung und Werte Initialisierung

Verfasst: Samstag 25. April 2020, 20:13
von __blackjack__
@m.g.o.d: Vorweg: Wenn als Funktion(en) alles prima funktioniert, warum dann Klassen? Klassen sind kein selbstzweck, die verwendet man wenn sie Sinn machen. Nicht um einfache Funktionen komplizierter zu schreiben. Wenn eine Klasse nur eine `__init__()` und eine weitere Methode hat, ist das in der Regel ein „code smell“ und man sollte begründen können warum das nicht einfach nur eine Funktion ist. Nur eine `__init__()` geht bei Datenklassen in Ordnung, dann hat man aber in der Regel auch Funktionen die etwas mit diesen zusammengefassten Daten machen. Und da werden dann auch Daten sinnvoll zusammengefasst.

Das was Du da als ”Klassen” geschrieben hast macht keinen Sinn. Was bitte ist ein URL-Master und was ein URL-Slave?

Von den Argumenten der `__init__()`-Methoden beider ”Klassen” wird kein einziges verwendet. Warum sind das dann Argumente? Das macht überhaupt keinen Sinn.

Bei `URL_MASTER` ist der Name `self.url` falsch, weil das keine URL ist, sondern eine Antwort auf eine Anfrage an den Webserver. Und die wird erst geschlossen und *dann* wird versucht die Zeilen zu lesen. Das geht ganz offensichtlich nicht. Ich sehe auch nicht warum das Antwort-Objekt überhaupt an das Objekt gebunden werden muss. Es macht auch keinen Sinn die Liste mit den Zeilen in eine Zeichenkette mit der Repräsentation dieser Liste umzuwandeln. Und diese Repräsentation eine Zeilenliste in einer Unterklasse zu versuchen als HTML-Quelltext an `BeautifulSoup` zu verfüttern ist noch unsinniger, weil auch das nicht geht. `BeautifulSoup` ist nirgends definiert.

Vererbung ist auch nicht dazu gedacht das Ergebnis eines Verarbeitungsschritts an den nächsten weiterzugeben. Das ist eine komplett falsche Aufteilung.

Namen KOMPLETT_GROSS sind für Konstanten, nicht für Klassen. Die werden `MixedCase` geschrieben, also `UrlMaster` und `UrlSlave`.

Nach der Abarbeitung der `__init__()` sollte man ein Objekt in einem benutzbaren Zustand haben. In der `__init__()` sollte nicht ”das Programm” ablaufen, die sollte wirklich nur das Objekt initialisieren. Möglichst einfach, damit man zum Testen einfach solche Objekte erstellen. Komplexere Sachen hat man üblicherweise in Klassenmethoden. Benutzerinteraktion gehört da in der Regel gar nicht rein.

Nochmal: Klassen üben geht nicht in dem man ``class`` schreibt und dann da *irgendwas* rein steckt. Wichtig beim lernen von Klassen ist auch wann man sie *nicht* verwendet.

Re: Python Klassenvererbung und Werte Initialisierung

Verfasst: Sonntag 26. April 2020, 15:49
von m.g.o.d
Hallo Zusammen,

danke für eure Antworten. Ich hab ein bisschen was gelernt, allerdings scheinen Klassen für mein Programm irgendwie nicht das richtige zu sein.

Der Grund, warum ich den Quellcode in Klassen schreiben wollte, war einfach, da es der Übersichtlichkeit dienen soll, wenn das ganze größer wird.

Schönen Sonntag zusammen.