Ausgabe


BasicC

Erfahrenes Mitglied
Python:
class student:
    vorname = ""
    nachname = ""
    matrikelnummer = 0
    geburtsdatum = 0
    note = 0
    kurs = ""

    def __repr__(self):
       return '{vorname:' + str(self.vorname) + ', nachname:' +str(self.nachname) +',''matrikelnummer:' + self.matrikelnummer + ','  'geburtsdatum:' +self.geburtsdatum+ '}'





o = student('Mein', 'Name', '123456', '01.01.02')
print(o)

Ich habe folgendes Problem erstens weiß ich nicht, ob mein Code stimmt :) zweitens gibt er keine Ausgabe von diesem Code

TypeError: This constructor takes no arguments ist die Fehlerausgabe
 

Technipion

Erfahrenes Mitglied
Hey BasicC,
TypeError: This constructor takes no arguments ist die Fehlerausgabe
das kommt wahrscheinlich daher, dass du der Klasse keinen Konstruktor gegeben hast. Python fügt also under the hood den Standardkonstruktor hinzu:
Python:
class Foo:
    def __init__(self): # Standard-Konstruktor
        pass # tue nichts

Allerdings rufst du dann weiter unten den Konstruktor von student auf, und übergibst ihm Parameter. Aber wie soll das in die Klasse verwurstelt werden?

Lösungsvorschläge:
1) Benutze den Standardkonstruktor und setze die Felder manuell:
Python:
o = student()
o.vorname = 'Mein'
o.nachname = 'Name'
o.matrikelnummer = '123456' # warum ein str und kein int?
o.geburtsdatum = '01.01.02'
print(o)

2) Die pythonische Variante: Füge einen Konstruktor hinzu:
Python:
class student:
    def __init__(self, vorname, nachname, matrikelnummer, geburtsdatum):
        self.vorname = vorname
        self.nachname = nachname
        self.matrikelnummer = matrikelnummer
        self.geburtsdatum = geburtsdatum
        self.note = 0
        self.kurs = ''

    def __repr__(self):
       return '{vorname:' + str(self.vorname) + ', nachname:' +str(self.nachname) +',''matrikelnummer:' + self.matrikelnummer + ','  'geburtsdatum:' +self.geburtsdatum+ '}'


o = student('Mein', 'Name', '123456', '01.01.02')
print(o)

Bemerkung: Wie Luciano Ramalho in seinem großartigen Buch "Fluent Python" beschreibt, bietet es sich an im Konstruktor an die Konstruktoren der Standard-Datentypen zu delegieren, dadurch behalten wir (der Entwickler der Klasse) die Kontrolle darüber, welchen Typ die Felder tatsächlich haben. Das ganze sieht dann in etwa so aus:
Python:
from datetime import date


class student:
    def __init__(self, vorname, nachname, matrikelnummer, geburtsdatum):
        self.vorname        = str(vorname)
        self.nachname       = str(nachname)
        self.matrikelnummer = int(matrikelnummer)
        self.geburtsdatum   = date.fromisoformat(geburtsdatum)
        self.note           = int(0) # explicit
        self.kurs           = str()  # explicit

    def __repr__(self):
       return '{vorname:' + str(self.vorname) + ', nachname:' + str(self.nachname) +',''matrikelnummer:' + self.matrikelnummer + ','  'geburtsdatum:' +self.geburtsdatum+ '}'


o = student('Mein', 'Name', '123456', '2002-01-01')
print(o)

Noch eine Bemerkung: Seit PEP 484 gibt es in Python Type Hints, und viele Entwickler benutzen sie aktiv. Bei sehr großen Projekten kann ich das in der Tat sogar nachvollziehen, allerdings verwende ich sie für meine Projekte nicht, da sie meiner Meinung nach in so kleinem Maßstab mehr Verwirrung schaffen als sie lösen.

Und noch eine Bemerkung: Anstatt in __repr__ verkettete String-Verknüpfung zu benutzen, kannst du auch direkt Python's Formatting verwenden, seit PEP 498 gerne auch mit F-Strings:
Python:
from datetime import date


class student:
    def __init__(self, vorname, nachname, matrikelnummer, geburtsdatum):
        self.vorname        = str(vorname)
        self.nachname       = str(nachname)
        self.matrikelnummer = int(matrikelnummer)
        self.geburtsdatum   = date.fromisoformat(geburtsdatum)
        self.note           = int(0) # explicit
        self.kurs           = str()  # explicit

    def __repr__(self):
        return (f"student({self.vorname!r}, "
                f"{self.nachname!r}, "
                f"{self.matrikelnummer!r}, "
                f"{self.geburtsdatum!r})"
                )
    
    def __str__(self):
        return (f"student('{self.vorname}', "
                f"'{self.nachname}', "
                f"{self.matrikelnummer}, "
                f"'{self.geburtsdatum}')"
                )


o = student('Mein', 'Name', '123456', '2002-01-01')
print(repr(o))
print(o)

o_rekonstruiert = eval(str(o))
print(repr(o_rekonstruiert))
print(o_rekonstruiert)

Wie du siehst, habe ich hier auch noch __str__ implementiert. Und schau dir auch den Test ganz unten an: In Python gilt es als best practice, wenn die String-Repräsentation im Prinzip der Code ist, der einem genau dieses Objekt erzeugen würde.

Gruß Technipion
 

BasicC

Erfahrenes Mitglied
Python:
class student:

    def __str__(self, vorname, nachname, matrikelnummer, geburtsdatum):
        self.vorname = vorname
        self.nachname = nachname
        self.matrikelnummer = matrikelnummer
        self.geburtsdatum = geburtsdatum



    def note_eintragen(self, kursname, kursnote):
        self.kname = kursname(input("Kursname: "))
        self.knote = kursnote(float(input("Kursnote: ")))
        print(kursname)
        print(kursnote)

    def noten_berichten(self):
        print(student.note_eintragen())

    def noten_schummeln(self):
        print("")



print(student.__str__("Mein", "Name", 123345, "01.01.2000"))

ich hatte es mittlerweile bis hier her geschafft, deine Lösung ist natürlich die viel bessere. Die Lösung klappt von mir nicht. Ich hätte gerne bei der Funktion note_eintragen den Kursnamen und die Kursnote eintragen wollen, doch das klappt nicht...