Seite 1 von 1

Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 14:00
von rennmaus
Hallo,
Für euch wahrscheinlich kein Problem, für mich aber schon ;)
Folgendes Problem. Ich habe folgenden Code:

Code: Alles auswählen

class Hallo:

    def schreiben(self):
        print("Hallo")

print(Hallo.schreiben())

jetzt bekomme ich aber, wenn ich diesen ausführen will eine Fehlermeldung:

Code: Alles auswählen

    print(Hallo.schreiben())
TypeError: schreiben() missing 1 required positional argument: 'self'
Woran liegt das? Ich muss doch eigentlich kein Argument angeben, außer dem "self", weil das ja in einer Klasse drin steht...

Mfg
Christian

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 14:04
von sparrow
"self" ist verweist aber immer innerhalb der Klasse auf die Instanz der Klasse. Du hast aber die Klasse nie instanziert.

Oder anders: Klassen sind nicht eine Bündelung von Funktionen sondern repräsntieren ein Objekt.

Leg doch zur Übung eine Klasse an, die eine Person repräsentiert. Der Klasse muss man bei der instanzierung einen Namen als Parameter mitgeben und die Person kann ihren Namen sagen.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 14:28
von rennmaus

Code: Alles auswählen

class Tom:
    def Name(self, Name):
        Name='Tom'
    def Alter(self, Alter):
        Alter='18'
    def Brüder(self, Brüder):
        Brüder='Toom'
so in etwa?

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 14:37
von Sirius3
@rennmaus: nein, die vier Methoden machen alle gar nichts. Da solltest Du nochmal zurück zum Grundlagentutorial, und nachlesen was Funktionen und Parameter und Variablen sind.

Eine Klasse ist eine Blaupause, also keine konkrete Person, sondern eine Abstrakte Person. Konkret wird sie erst durch die Instanziierung.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 14:39
von rennmaus
Okeeeeeee! Danke

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 15:06
von snafu
Vielleicht ganz banal erklärt: Eine Klasse kann man sich auch als Klassenraum in der Schule vorstellen. Tische, Tafel, usw stehen schon bereit. Zu einem konkreten Objekt wird die Klasse, wenn ihr Lehrer und Schüler "übergeben" werden. Somit könnte man mehrere Klassen hintereinander aufbauen. Die Einrichtung ist immer gleich, aber die Personen in der Klasse sind jeweils andere Lehrer und Schüler. Auch die Bezeichnung der Klasse ist immer anders, z.B. 4a, 4b, 4c, oder man gibt eine Position in der Schule an: 1. Etage, dritter Raum links. :)

EDIT: Wobei letzteres besser ein Lageplan wüsste, bei dem man die Position der Klasse 4A abfragen könnte.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 18:40
von rennmaus

Code: Alles auswählen

import time

class Auto:
    geschwindigkeit=0
    class Opel:
        geschwindigkeit=0
        def beschleunigen(self, wert):
            self.geschwindigkeit+=wert)
            print("Geschwindigkeit (Opel):", self.geschwindigkeit)
    
        def bremsen(self, wert):
            self.geschwindigkeit-=wert
            print("Geschwindigkeit (Opel):", self.geschwindigkeit)
        
        def stehen(self):
            self.geschwindigkeit-=self.geschwindigkeit
            print("Das Auto (Opel) steht(",self.geschwindigkeit,")")

    class Ferrari:
        geschwindigkeit=0
        def beschleunigen(self, wert):
            self.geschwindigkeit+=wert
            print("Geschwindigkeit (Ferrari):", self.geschwindigkeit)
  
        def bremsen(self, wert):
            self.geschwindigkeit-=wert
            print("Geschwindigkeit (Ferrari):", self.geschwindigkeit)
        
        def stehen(self):
            self.geschwindigkeit-=self.geschwindigkeit
            print("Das Auto (Ferrari) steht(",self.geschwindigkeit,")")

Auto.Opel.beschleunigen(100)
Ich habe ein wenig rumprobiert, jetzt ist es so, dass die beschleunigung vom Opel nicht geht. Folgende Fehlermeldung:
[codeAuto.Opel.beschleunigen(100)
TypeError: beschleunigen() missing 1 required positional argument: 'wert'][/code]
Das hatte ich schonmal, weiß aber nicht mehr wie ich das gelöst habe. Bestimmt wieder etwas ganz einfaches, was mir gerade entfallen ist.
@snafu Danke für die ausführliche Erklärung, werde sie immer mal wieder aufmerksam durchlesen.

Mfg
Christian

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 19:00
von sparrow
Nein. Das macht von den Klassen in Klassen keinen Sinn und du hast noch immer nicht verstanden, was der Unterschied zwischen einer Klasse und deren Instanz ist. Ohne ein Verständnis für Objektorientierung funktioniert es nicht.

Du musst dir irgendwo anlesen, wie Objektorientierte Programmierung und Klassen funktionieren. Das ist grundlegend und mehr oder weniger für alle Progammiersprachen gültig.
Wie man Klassen in Python verwendet erklärt das Tutorial.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 19:22
von snafu
Der Opel und der Ferrari sollten besser die konkreten Objekte sein. __init__() bekäme dann die Modellbezeichnung und die Höchstgeschwindigkeit übergeben. Wenn man Ableitung drin haben will (die IMHO gerade in Sprachen wie Python ziemlich überschätzt wird), dann könnte man Auto von Fahrzeug erben lassen und zusätzlich Motorrad und LKW von selbiger ableiten.

Gerade solche stumpfen Beispiele wie Auto findet man übrigens tausendfach im Netz. Da kannst du dir also bestimmt etwas abgucken. ;)

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 19:28
von rennmaus
Ich hole mir meine Informationen, meistens vom The morpheus Tutorials. Eigentlich erklärt er es ganz gut, aber manchmal muss ich mir das Video dann mehrmals anschauen...

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 21:55
von rennmaus
Aber sind Instanzen nicht vereinfacht gesagt, verschiedene Namen für die Klasse? Meine Frage ist schlecht beschrieben, aber in einem Buch steht dazu folgendes :
"Nach der bereits beschriebenen Klassendefinition werden zunächst zwei Objekte der Klasse Fahrzeug erzeugt,hier mit dem Namen Opel und Volvo (opel=Fahrzeug(), volvo=Fahrzeug ()). Diesen Vorgang nennt man auch: Instanzen einer Klasse erzeugen.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Freitag 9. Oktober 2020, 22:20
von sparrow
@rennmaus: Der "Name" der Klasse in deinem Text ist "Fahrzeug".
opel = Fahrzeug() erzeugt eine Instanz (also instanziert) der Klasse "Fahrzeug" und bindet sie an den Namen "opel".

Hast du dir den Teil des Tutorials angeschaut, den ich verlinkt habe? Das ist kein Video, beinhaltet aber alle Informationen.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Samstag 10. Oktober 2020, 05:09
von snafu
Du hast anscheinend nach wie vor nicht den Unterschied zwischen Klasse bzw Typ und konkretem Objekt verstanden. Wenn ich etwas vom Typ Benutzer habe, dann wäre "rennmaus" ein Objekt dieser Klasse. Bei Autos könnte man ein Klassenmodell grundsätzlich auch als Vererbungshierachie mit verschiedenen Autotypen darstellen. Das ist aber nur dann nötig, wenn die Klassen unterschiedliche Methoden haben, d.h. andere Implementierungen oder zusätzliche Methoden. Wenn du im "Bauplan" deiner Klasse Opel also sinnvoll darstellen kannst, was ihn fundamental von einem Volvo unterscheidet, dann nutze Vererbung. Meistens ist es aber besser, wenn beide Automodelle konkrete Objekte vom Typ Auto sind, die dann eben unterschiedliche Eigenschaften und eine andere Typenbezeichnung haben. Die grundlegenden Eigenschaften / Fähigkeiten, sind aber trotzdem die eines Autos.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Samstag 10. Oktober 2020, 14:02
von rennmaus

Code: Alles auswählen

import time

class Auto:
    geschwindigkeit=0
    def beschleunigen(self, wert, Auto):
        self.geschwindigkeit+=wert
            
        print("Geschwindigkeit (",Auto,"):", self.geschwindigkeit)
    
    def bremsen(self, wert, Auto):
            self.geschwindigkeit-=wert
            print("Geschwindigkeit (",Auto,"):", self.geschwindigkeit)
        
    def stehen(self):
            self.geschwindigkeit-=self.geschwindigkeit
            print("Das Auto steht(",self.geschwindigkeit,")")

class Opel(Auto):
    def bremsen(self, wert):
        wert2=wert/5
        wert3=wert/10
        wert2=int(wert2)
        for i in range(wert2):
            self.geschwindigkeit-=wert
            zeit=0.05*wert
            time.sleep(zeit)
            print("Geschwindigkeit (Opel)", self.geschwindigkeit,"km/h")

    def beschleunigen(self, wert):
        wert2=wert/5
        wert3=wert/10
        wert2=int(wert2)
        for i in range(wert2):
            self.geschwindigkeit+=wert
            zeit=self.geschwindigkeit/9
            time.sleep(zeit)
            print("Geschwindigkeit (Opel)",self.geschwindigkeit,"km/h")

    def stehen(self):
        zeit=0.05*self.geschwindigkeit
        time.sleep(zeit)
        self.geschwindigkeit-=self.geschwindigkeit
        print("Geschwindigkeit (Opel)", self.geschwindigkeit,"km/h")
            
        

class Ferrari(Auto):
    def bremsen(self, wert):
        wert2=wert/10
        wert2=int(wert2)
        for i in range(wert2):
            self.geschwindigkeit-=10
            zeit=(self.geschwindigkeit/50)/2
            time.sleep(zeit)
            print("Geschwindigkeit:", self.geschwindigkeit,"km/h")

    def beschleunigen(self, wert):
        wert2=wert/10
        wert2=int(wert2)
        for i in range(wert2):
            self.geschwindigkeit+=10
            zeit=(self.geschwindigkeit/50)/10
            time.sleep(zeit)
            print("Geschwindigkeit:", self.geschwindigkeit,"km/h")

    def stehen(self):
        wert=self.geschwindigkeit/10
        wert=int(wert)
        wert2=wert-1
        for i in range(wert2):
            zeit=0.02*wert
            time.sleep(zeit)
            self.geschwindigkeit-=10
            print("Auto bremst ab (",self.geschwindigkeit,"km/h)")
        print("Auto steht(0 km/h)")


opel=Opel()   
ferrari=Ferrari()
Dazu habe ich das als ausführung geschrieben:

Code: Alles auswählen

import Test, time

T=Test()

T.ferrari.beschleunigen(80)
time.sleep(1)
T.ferrari.bremsen(30)
T.ferrari.beschleunigen(20)
T.ferrari.stehen()
Ist es besser geworden? (Schaut nur auf den ferrari, Opel ist noch in Arbeit, die Vererbung, war eigentlich unnötig, aber egal ;))

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Samstag 10. Oktober 2020, 14:18
von __blackjack__
@rennmaus: Ein bisschen besser ja, aber da ist immer noch einiges falsch. `geschwindigkeit` hat nichts auf Klassenebene zu suchen. Und es fehlt eine `__init__()`.

Und die Vererbung ist in der Tat unnötig, und eventuell nicht so wie *Du* vielleicht denkst: Nicht `Auto` ist unnötig, sondern `Opel` und `Ferrari` sind unnötig. Da steht so gut wie der gleiche Code in beiden Klassen bei den Methoden. Beschleunigen und Bremsen und stehen stehen ist vom Grunde her bei allen Autos gleich. Die unterscheiden sich in Motorleistung, Gewicht, und Bremsleistung. Das sind neben dem Namen die Unterschiede. Und diese Unterschiede sind die Daten die man einem Auto beim erstellen eines Exemplars (a.k.a. Instanz) mit gibt. Der Code sorgt dann mit Hilfe dieser Daten für das entsprechende Verhalten. Und dieser Code ist für alle Autos *gleich*, steht also nur *einmal* im Code in *einer* allgemeinen `Auto`-Klasse.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Samstag 10. Oktober 2020, 15:24
von snafu
Hier mal ein Beispiel wie man das objektorientiert umsetzen kann, indem man verschiedene Parameter übergibt.

Es ist ein leichter Mischmasch aus Englisch und Deutsch vorhanden, da "geschwindigkeit" und "hoechstgeschwindigkeit" mir einfach zu sperrig waren. Andererseits wollte ich größtenteils im Deutschen bleiben, damit es auch ohne Wörterbuch verständlich ist. ;)

Code: Alles auswählen

class Auto:
    def __init__(self, name, top_speed):
        self.name = name
        self.top_speed = top_speed
        self.speed = 0

    def beschleunigen(self, kmh):
        """
        Erhöhe Geschwindigkeit um angegebene km/h.
        Dabei wird top_speed nicht überschritten.
        """
        self.speed = min(self.speed + kmh, self.top_speed)

    def bremsen(self, kmh):
        """
        Verringere Geschwindigkeit um angegebene km/h.
        Es wird garantiert, dass die Geschwindigkeit
        nicht unter 0 km/h fallen kann.
        """
        self.speed = max(self.speed - kmh, 0)

    def anhalten(self):
        """
        Bremse das Auto vollständig ab.
        """
        # self.speed = 0
        self.bremsen(self.speed)


def main():
    opel = Auto("Opel", 180)
    ferrari = Auto("Ferrari", 350)
    for gang_nr in range(1, 7):
        opel.beschleunigen(gang_nr * 10)
        ferrari.beschleunigen(gang_nr * 20)
        print(f"Der Opel fährt jetzt {opel.speed} km/h "
              f"und der Ferrari fährt {ferrari.speed} km/h. "
              f"Beide sind in Gang Nummer {gang_nr}.")

if __name__ == "__main__":
    main()
Das allmähliche Abbremsen sowie eine sinnvolle Nutzung der Autonamen könnten nun Aufgaben für den TE darstellen. :)

Wenn man das richtig macht, würde man auch Fehlerfälle abfangen, wie z.B. die Angabe einer negativen Höchstgeschwindigkeit. Sprengt hier aber IMHO den Rahmen.

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Samstag 10. Oktober 2020, 20:35
von rennmaus
Wow, danke! Solche Beispiele helfen mir persönlich immer sehr. Daraus kann ich mir dann die Nutzung erschließen. Vielen Dank!

Mfg
Christian

Re: Fehlermeldung bei Erstellung von Klasse

Verfasst: Samstag 10. Oktober 2020, 21:49
von snafu
Gerne doch. Falls noch Fragen aufkommen (und das werden sie mit ziemlicher Sicherheit), dann stell sie hier ruhig. Weiterhin schadet vorheriges selber Informieren (entweder mit den Videos oder auch mal aus anderen Quellen) natürlich auch nicht. :)