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