Vielen, vielen Dank. Das tat gut. Sehr interessant. Ich habe wieder Lust auf Python. Ich konnte die Tuts nicht mehr ertragen, die mir eine halbe Stunde lang erklären was Variablen sind und dass man mit ihnen rechen kann, um dies dann später noch mal zu erklären. Dieses Video war für mich ein Befreiungsschlag. Es gibt sie noch, die sich wirklich auskennen. :-)
Merci! Ist aber manchmal ein Spagat, weil viele Leute sich zu früh auf so ein Video stürzen und dann disliken, weil sie grundlegende Konzepte nicht kennen und dann nicht hinterherkommen :-)
Erst mal vielen Dank für das umfangreiche Video, welches ich die letzten Tage auch vollständig durchgegangen bin. Da hast du ja tatsächlich das wichtigste aus dem Bereich OOP abgehandelt. Ich denke mal, dass ich das meiste verstanden habe, auch wenn ich einiges noch einmal vertiefen muss. Nur beim Thema Mixins + Multiple Inheritance musste ich noch ein paar externe Quellen zu Rate ziehen. Ich könnte mir vorstellen, dass es nicht nur mir so ging. Vielleicht kannst du da mal noch ein Video zum Unterschied und dem speziellen Einsatzzweck machen und das Thema vertiefen.
Danke für den Kommentar. Was genau hat dir bei den Mixins gefehlt? Ein praktischeres Beispiel und/oder auch etwas beim Inhalt um das Thema zu verstehen?
@@codingcrashkurse6429 Einfach eine Erläuterung, die an einem praktischen Beispiel zeigt wenn man ein Mixin einsetzt und wenn regular inheritance. Ich denke mal, dass das inhaltliche Verständnis dabei automatisch mit verbessert wird.
Super kompaktes Tutorial zum Thema, herzlichen Dank! Beim Descriptor-Beispiel bin ich nicht ganz hinterher gekommen, da es m.M.n. eine einfachere Lösung gibt. Der relevante Punkt fehlt evtl. noch weiter vorn in expliziter Nennung: Properties, die direkt in der Klasse deklariert werden, sind für alle Instanzen gleich. Daraus resultiert, dass archer2 die Properties von archer1 ändert. Wenn die Deklaration der Properties aber in __init__ passiert, werden für jede Instanz unterschiedliche Objekte/Properties erzeugt. Musste das mal an anderer Stelle (sehr mühsam) herausfinden. Sich das __init__ und das lästige self. sparen zu wollen kann schwere Nebenwirkungen auslösen ;) Leider tritt das Problem anscheinend auch bei einer dataclass auf, sofern eine Property als Objekt (z.B. wieder Descriptor) mit default deklariert wird.
Danke für das Feedback. Ich sage ganz ausdrücklich, dass ich in dem Video niemals das best practice zeige, sondern immer nur Konzepte. Ich persönlich habe das Deskriptor Protokoll noch nie nutzen müssen.
Ich bin begeistert, wie locker du programmierst und nebenbei noch reden kannst. Momentan habe ich noch ein Problem damit die Dinge akustisch zu verstehen. Das ist so wahnsinnig schnell. Ist das wirklich die Originalgeschwindigkeit?
Tolles Video. Hätte aber eine Frage in Bezug auf Deskriptors: Warum erstellen wir nicht die get und set Methoden nicht innerhalb der Archer Class? Ist das jetzt für das Video zur Veranschaulichung so oder wird es grundsätzlich so gemacht?
Bin gerade beim Anfang deines Tutorials und habe beim Teil (Basics: Klasse und Instanzen Minute 14:24) alles so gemacht wie du es gezeigt hast, allerdings komme ich bei der Aufgabe nicht weiter da der folgende Fehler auftritt TypeError: Archer() takes no arguments. Ich habe meinen Code unten reinkopiert. Ich danke wenn du kurz reinschaust und mir weiterhilfst natürlich nur wenn du Zeit hast. class Archer: def __int__(self, hp, mana, arrows): self.hp = hp self.mana = mana self._arrows = arrows def walk(self): print(f"Ich bin {self} und laufe") def shoot(self): if self._arrows > 0: self._arrows -= 1 print(f"Bogenschütze hat geschossen, noch {self._arrows} Pfeile übrig") else: print("Bogenschütze hat keinen Pfeil mehr") archer1 = Archer(100, 0, 3) archer2 = Archer(90, 10, 3) print(archer1.hp) archer2.arrows = 0 archer2.shoot() print(archer2.__dict__)
Da wäre das Video 5x und mein3 Hände blutig:p. Nee im Ernst, in Java ist nur die Syntax anders, das kannst du dir auch von gpt4 in Java übersetzen lassen. Nur ein paar Dinge sind anders
@@codingcrashkurse6429 Danke für dein Schaffen und deine Antwort! Ich habe Chatgpt gefragt.... Allerdings, hat er keinen Zugriff auf dein Video hier, und ich kann "Es" natürlich nicht alles aufschreiben..... Daher wird der Weg anders werden...... Ich habe genug Tutorials und Bücher zum Lernen... aber muss mich an das Lernen an sich gewöhnen... ist leider zu lange her.... Naja ich gebe nicht auf! :D
du meinst ohne name mangling, also mit einem Unterstrich. Wenn ja - da es sich um nur um eine Konvention handelt, verhält es sich hier genauso wie bei "öffentlichen" methoden. Wobei es ja im Prinzip in Python ohnehin nur öffentliche Methoden und Attribute gibt :-)
Hallo, danke dir für die sehr ausführliche Darstellung. Ich habe eine Frage zu deinem Beispiel der MixinClass. 1:30:04 Zeile 9. Wenn ich die SuperWalkMixin Klasse erstelle, gibt mir mein Editor (VS Code, mit Pylance) einen Fehler für die .walk() Methode von {super().walk()} aus. Fehlermeldung: "Cannot access member "walk" for type "object"⏎ Member "walk" is unknown". Meine laienhafte Vermutung wäre jetzt, das die SuperWalkMixin Klasse ja noch nicht weiß, welche ihre Superklasse sein soll und deswegen rummeckert. Ausgeführt wird der Code dennoch ohne Probleme, sowohl im Jupyter Notebook, als auch in einer normalen .py Datei. Gebe ich der SuperWalkMixin Klasse die Archerklasse als Superklasse mit (class SuperWalkMixin(Archer):" dann verschwindet die Fehlermeldung und es funktioniert ebenfalls. Mein Gedanke ist, das dies aber eigentlich nicht die Lösung sein kann, da ich die SuperWalkMixin Klasse ja eventuell auch für eine andere Klasse, zB Wizard verwenden möchte. Und dann ist es ja Essig, da ich bereits die Archer Klasse da hab. Ich hoffe ich konnte das einigermaßen verständlich beschreiben. Ein Screenshot hab ich mal hochgeladen: abload.de/img/fehlerqoid9.png Grüße und mach weiter so.
Hi! Cool, dass du so weit durchgehalten hast ;-). Das Problem ist, dass super() hier theoretisch auf die object class zugreift und diese natürlich keine walk method implementiert hat. Hier Archer als superclass zu verwenden ist aber keine Lösung, weil es der Idee eines mixins wiederspricht (wie du richtig gesagt hast). Mir würden hier zwei Lösungen einfallen: Du sagst pylint, es soll das Ganze ignorieren: # type: ignore (über der methode) Du checkst es im Code z.B. mit hasattr(super(), "walk") # do stuff. MÜSSTE funktionieren. Vielleicht gibt es da noch schönere Lösungen, aber das wäre das was mir gerade dazu einfällt.
@@codingcrashkurse6429 Danke für die Erklärung. Das #type: ignore hatte ich bereits hinzugefügt. War mir allerdings nicht sicher, ob das in dem Fall gut wäre. Weil ich könnte so ziemlich jede Fehlermeldung, sei es von black, flake8, Pylance oder anderen Lintern wegdrücken. Nur davon lerne ich ja auch nicht, "besseren" Code zu schreiben und Fehler zu vermeiden. Drum dachte ich mir, frag ich lieber mal nach :)
Eine Frage zu den Dekorators für Setter und Getter: Warum ist das so unterschiedlich gemacht? Wäre es nicht verständlicher wenn es @property_get, @property_set und @property_del genannt worden wäre? Was ist der Grund für diese unterschiedliche Namenskonvention?
Die Syntax @property in Python fungiert als Dekorator, der eine gegebene Funktion in eine Getter-Funktion transformiert. Wenn du danach @attribut.setter und @attribut.deleter nutzt, erweiterst du die zuvor durch @property erstellte Eigenschaft um zusätzliche Funktionen. Die Schreibweise leitet sich also direkt aus der Implementierung ab, sprich es gibt keinen setter ohne getter, aber sehr wohl einen getter ohne setter.
@@codingcrashkurse6429 Danke für die schnelle Antwort. Ein guter Hinweis, dass ein Setter oder Deleter nur dann geht, wenn vorher die @property definiert wurde. Ich war verwundert darüber, dass Python bei den Namen für diese Art von Dekoratoren so verfährt. Einmal nur den Bezeichner @property, dann aber die Bezeichner @attribut.setter und @attribute.deleter. Hier hätte ich, wie in anderen Sprachen auch, die Bezeichner in der Art wie @property_set, @property_get erwartet. Naja, nun habe ich es verstanden und nutze es halt so🙂 Vielen Dank, Klaus
@@codingcrashkurse6429 Ich habe mich aufgrund Deiner Angaben nochmal mit Getter und Setter beschäftigt. Und nun habe ich auch begriffen, warum diese Namenskonvention so wichtig ist. Es geht nämlich auch das Folgende: @property # Getter Standard def n(self): return self.name # Setter für obiges def n(self) mit dem Namen n. Also n = 'NeuerName' @n.setter def n(self, neu): self.name = neu # Und danach war es mir klar: # Setter für def n() mit namen blablabla, # also geht dann blablabla = "NeuerName" @n.setter def blablabla(self, neu): self.name = neu Vielen Dank nochmal, Klaus
Bin die erste 30 min des Video gut durchgekommen (Programmieren nachvolzogen), dann allerdings wachsen die Schwierigkeiten ... Meines Erachtens sollte der Code immer auf die Teile beschränkt werden die für die Erklärung notwendig sind. Vor allem Sinn und Zweck sind mir dann ab der Hashfunktion manchmal nicht mehr klar
@@codingcrashkurse6429 Was ich (sehr?) gut finde dass der Kurs Beispiele bringt, Anwendungsmöglichkeiten aufzeigt. Sehr ? deswegen weil ich in Computerspielen nicht bewandert bin
Ich vermute, ab der Zeitmarke 50:02 hat sich ein Fehler eingeschlichen. Wenn ich next(Company) aufrufe, bekomme ich einen Fehler: Maximum Recursion depth exceeded. Ich habe Zeile 72 abgeändert new_archer = self.archers[self.index] Gibt es noch eine elegantere Art?
⭐⭐⭐⭐⭐
Entlich mal eine Komplette Erklärung die auf das Grundverständnis eingeht.
Voll toll👍
Danke!
Freut mich dass es dir gefallen hat:)
Vielen, vielen Dank. Das tat gut. Sehr interessant. Ich habe wieder Lust auf Python. Ich konnte die Tuts nicht mehr ertragen, die mir eine halbe Stunde lang erklären was Variablen sind und dass man mit ihnen rechen kann, um dies dann später noch mal zu erklären. Dieses Video war für mich ein Befreiungsschlag. Es gibt sie noch, die sich wirklich auskennen. :-)
Merci! Ist aber manchmal ein Spagat, weil viele Leute sich zu früh auf so ein Video stürzen und dann disliken, weil sie grundlegende Konzepte nicht kennen und dann nicht hinterherkommen :-)
Mega Video!
Vielen Dank für deinen Aufwand
Gerne, wozu hat man denn Urlaub:D
Klasse Struktur und super komplett Kurs👍
Bin gerade bei der Hälfte und feier das Video extrem. Hat mich gut abegholt nach der anfänglichen Tutorialphase.
Freut mich :)
Richtig gut investierte zweieinhalb Stunden. Perfekte Geschwindigkeit und Tiefe. So muss ein Tutorial sein!
Wow, Respekt da komplett durch zu gehen:)
Super gut erklärt, danke sehr.
Erst mal vielen Dank für das umfangreiche Video, welches ich die letzten Tage auch vollständig durchgegangen bin. Da hast du ja tatsächlich das wichtigste aus dem Bereich OOP abgehandelt. Ich denke mal, dass ich das meiste verstanden habe, auch wenn ich einiges noch einmal vertiefen muss. Nur beim Thema Mixins + Multiple Inheritance musste ich noch ein paar externe Quellen zu Rate ziehen. Ich könnte mir vorstellen, dass es nicht nur mir so ging. Vielleicht kannst du da mal noch ein Video zum Unterschied und dem speziellen Einsatzzweck machen und das Thema vertiefen.
Danke für den Kommentar. Was genau hat dir bei den Mixins gefehlt? Ein praktischeres Beispiel und/oder auch etwas beim Inhalt um das Thema zu verstehen?
@@codingcrashkurse6429 Einfach eine Erläuterung, die an einem praktischen Beispiel zeigt wenn man ein Mixin einsetzt und wenn regular inheritance. Ich denke mal, dass das inhaltliche Verständnis dabei automatisch mit verbessert wird.
Super. Vielen lieben Dank dein geiles Video.
Du bist toll! Danke!
Fand ich sehr hilfreich!
ich habe mal versucht ein problem mit OOP zu lösen. jetzt habe ich eine "ProblemFabrik". :-)
Super kompaktes Tutorial zum Thema, herzlichen Dank!
Beim Descriptor-Beispiel bin ich nicht ganz hinterher gekommen, da es m.M.n. eine einfachere Lösung gibt. Der relevante Punkt fehlt evtl. noch weiter vorn in expliziter Nennung: Properties, die direkt in der Klasse deklariert werden, sind für alle Instanzen gleich. Daraus resultiert, dass archer2 die Properties von archer1 ändert. Wenn die Deklaration der Properties aber in __init__ passiert, werden für jede Instanz unterschiedliche Objekte/Properties erzeugt. Musste das mal an anderer Stelle (sehr mühsam) herausfinden. Sich das __init__ und das lästige self. sparen zu wollen kann schwere Nebenwirkungen auslösen ;)
Leider tritt das Problem anscheinend auch bei einer dataclass auf, sofern eine Property als Objekt (z.B. wieder Descriptor) mit default deklariert wird.
Danke für das Feedback. Ich sage ganz ausdrücklich, dass ich in dem Video niemals das best practice zeige, sondern immer nur Konzepte. Ich persönlich habe das Deskriptor Protokoll noch nie nutzen müssen.
Ich bin begeistert, wie locker du programmierst und nebenbei noch reden kannst. Momentan habe ich noch ein Problem damit die Dinge akustisch zu verstehen. Das ist so wahnsinnig schnell. Ist das wirklich die Originalgeschwindigkeit?
Ja war die Originalgeschwindigkeit ;-)
danke für das Video
Gerne! Danke für den Kommentar
Tolles Video. Hätte aber eine Frage in Bezug auf Deskriptors: Warum erstellen wir nicht die get und set Methoden nicht innerhalb der Archer Class? Ist das jetzt für das Video zur Veranschaulichung so oder wird es grundsätzlich so gemacht?
Geiles Video 👌🏽
Vielen Dank:)
Bin gerade beim Anfang deines Tutorials und habe beim Teil (Basics: Klasse und Instanzen Minute 14:24) alles so gemacht wie du es gezeigt hast, allerdings komme ich bei der Aufgabe nicht weiter da der folgende Fehler auftritt TypeError: Archer() takes no arguments. Ich habe meinen Code unten reinkopiert. Ich danke wenn du kurz reinschaust und mir weiterhilfst natürlich nur wenn du Zeit hast.
class Archer:
def __int__(self, hp, mana, arrows):
self.hp = hp
self.mana = mana
self._arrows = arrows
def walk(self):
print(f"Ich bin {self} und laufe")
def shoot(self):
if self._arrows > 0:
self._arrows -= 1
print(f"Bogenschütze hat geschossen, noch {self._arrows} Pfeile übrig")
else:
print("Bogenschütze hat keinen Pfeil mehr")
archer1 = Archer(100, 0, 3)
archer2 = Archer(90, 10, 3)
print(archer1.hp)
archer2.arrows = 0
archer2.shoot()
print(archer2.__dict__)
Du hast __int__ statt __init__ geschrieben
Danke sehr@@codingcrashkurse6429
Super Danke, das gibts nicht Zufällig auch für Java? :D
Da wäre das Video 5x und mein3 Hände blutig:p. Nee im Ernst, in Java ist nur die Syntax anders, das kannst du dir auch von gpt4 in Java übersetzen lassen. Nur ein paar Dinge sind anders
@@codingcrashkurse6429 Danke für dein Schaffen und deine Antwort! Ich habe Chatgpt gefragt.... Allerdings, hat er keinen Zugriff auf dein Video hier, und ich kann "Es" natürlich nicht alles aufschreiben..... Daher wird der Weg anders werden...... Ich habe genug Tutorials und Bücher zum Lernen... aber muss mich an das Lernen an sich gewöhnen... ist leider zu lange her.... Naja ich gebe nicht auf! :D
nices tutorial !
Vielen Dank !
gerne ;-)
danke ❤
Krass. Du hast einfach alles bis aufs kleinste detail erklärt
Das war der Plan :-D. Hoffe es har dir gefallen und vor allem geholfen 🙂
Könnte man das Problem mit dem Memory beim Deskriptor nicht auch mit der __del__ lösen?
Worauf beziehst du dich genau? Das Video ist lang und schon älter
Ne frage noch zum Vererben: Kann man private attribute und methods vererben irgendwie?
du meinst ohne name mangling, also mit einem Unterstrich. Wenn ja - da es sich um nur um eine Konvention handelt, verhält es sich hier genauso wie bei "öffentlichen" methoden. Wobei es ja im Prinzip in Python ohnehin nur öffentliche Methoden und Attribute gibt :-)
ehrenbro
Hallo, danke dir für die sehr ausführliche Darstellung.
Ich habe eine Frage zu deinem Beispiel der MixinClass.
1:30:04 Zeile 9. Wenn ich die SuperWalkMixin Klasse erstelle, gibt mir mein Editor (VS Code, mit Pylance) einen Fehler für die .walk() Methode von {super().walk()} aus. Fehlermeldung: "Cannot access member "walk" for type "object"⏎ Member "walk" is unknown". Meine laienhafte Vermutung wäre jetzt, das die SuperWalkMixin Klasse ja noch nicht weiß, welche ihre Superklasse sein soll und deswegen rummeckert.
Ausgeführt wird der Code dennoch ohne Probleme, sowohl im Jupyter Notebook, als auch in einer normalen .py Datei.
Gebe ich der SuperWalkMixin Klasse die Archerklasse als Superklasse mit (class SuperWalkMixin(Archer):" dann verschwindet die Fehlermeldung und es funktioniert ebenfalls.
Mein Gedanke ist, das dies aber eigentlich nicht die Lösung sein kann, da ich die SuperWalkMixin Klasse ja eventuell auch für eine andere Klasse, zB Wizard verwenden möchte. Und dann ist es ja Essig, da ich bereits die Archer Klasse da hab.
Ich hoffe ich konnte das einigermaßen verständlich beschreiben.
Ein Screenshot hab ich mal hochgeladen: abload.de/img/fehlerqoid9.png
Grüße und mach weiter so.
Hi! Cool, dass du so weit durchgehalten hast ;-).
Das Problem ist, dass super() hier theoretisch auf die object class zugreift und diese natürlich keine walk method implementiert hat. Hier Archer als superclass zu verwenden ist aber keine Lösung, weil es der Idee eines mixins wiederspricht (wie du richtig gesagt hast). Mir würden hier zwei Lösungen einfallen:
Du sagst pylint, es soll das Ganze ignorieren: # type: ignore (über der methode)
Du checkst es im Code z.B. mit hasattr(super(), "walk") # do stuff. MÜSSTE funktionieren.
Vielleicht gibt es da noch schönere Lösungen, aber das wäre das was mir gerade dazu einfällt.
@@codingcrashkurse6429 Danke für die Erklärung. Das #type: ignore hatte ich bereits hinzugefügt. War mir allerdings nicht sicher, ob das in dem Fall gut wäre. Weil ich könnte so ziemlich jede Fehlermeldung, sei es von black, flake8, Pylance oder anderen Lintern wegdrücken. Nur davon lerne ich ja auch nicht, "besseren" Code zu schreiben und Fehler zu vermeiden. Drum dachte ich mir, frag ich lieber mal nach :)
Eine Frage zu den Dekorators für Setter und Getter: Warum ist das so unterschiedlich gemacht? Wäre es nicht verständlicher wenn es @property_get, @property_set und @property_del genannt worden wäre? Was ist der Grund für diese unterschiedliche Namenskonvention?
Die Syntax @property in Python fungiert als Dekorator, der eine gegebene Funktion in eine Getter-Funktion transformiert. Wenn du danach @attribut.setter und @attribut.deleter nutzt, erweiterst du die zuvor durch @property erstellte Eigenschaft um zusätzliche Funktionen. Die Schreibweise leitet sich also direkt aus der Implementierung ab, sprich es gibt keinen setter ohne getter, aber sehr wohl einen getter ohne setter.
@@codingcrashkurse6429 Danke für die schnelle Antwort. Ein guter Hinweis, dass ein Setter oder Deleter nur dann geht, wenn vorher die @property definiert wurde.
Ich war verwundert darüber, dass Python bei den Namen für diese Art von Dekoratoren so verfährt. Einmal nur den Bezeichner @property, dann aber die Bezeichner @attribut.setter und @attribute.deleter. Hier hätte ich, wie in anderen Sprachen auch, die Bezeichner in der Art wie @property_set, @property_get erwartet. Naja, nun habe ich es verstanden und nutze es halt so🙂
Vielen Dank,
Klaus
@@codingcrashkurse6429
Ich habe mich aufgrund Deiner Angaben nochmal mit Getter und Setter beschäftigt. Und nun habe ich auch begriffen, warum diese Namenskonvention so wichtig ist.
Es geht nämlich auch das Folgende:
@property # Getter Standard
def n(self):
return self.name
# Setter für obiges def n(self) mit dem Namen n. Also n = 'NeuerName'
@n.setter
def n(self, neu):
self.name = neu
# Und danach war es mir klar:
# Setter für def n() mit namen blablabla,
# also geht dann blablabla = "NeuerName"
@n.setter
def blablabla(self, neu):
self.name = neu
Vielen Dank nochmal,
Klaus
archer = Archer bei 20:24 ist doch trotzdem eine Klasse und keine Instanz, sonst müsste es doch archer = Archer() heißen oder ?
Du hast Recht, hab ich die brackets vergessen. Bei der staticmethod funktioniert es ja trotzdem, daher ist es mir nicht aufgefallen
Bin die erste 30 min des Video gut durchgekommen (Programmieren nachvolzogen), dann allerdings wachsen die Schwierigkeiten ... Meines Erachtens sollte der Code immer auf die Teile beschränkt werden die für die Erklärung notwendig sind. Vor allem Sinn und Zweck sind mir dann ab der Hashfunktion manchmal nicht mehr klar
okay, danke für das Feedback
@@codingcrashkurse6429 Was ich (sehr?) gut finde dass der Kurs Beispiele bringt, Anwendungsmöglichkeiten aufzeigt. Sehr ? deswegen weil ich in Computerspielen nicht bewandert bin
@@FranzFakler Feedback welcome, ich plane für dieses Jahr eine Neuauflage dieses Kurses :)
#PUSHWITHCOMMENT
Ich vermute, ab der Zeitmarke 50:02 hat sich ein Fehler eingeschlichen.
Wenn ich next(Company) aufrufe, bekomme ich einen Fehler:
Maximum Recursion depth exceeded.
Ich habe Zeile 72 abgeändert
new_archer = self.archers[self.index]
Gibt es noch eine elegantere Art?
Super Tutorial.
Leider nervt die Hintergrundmusik.
Bitte abschalten
Hast du überhaupt mehr als eine Minute geschaut? Die Musik gibt es nur im intro
Bis auf das teils unnötige "Denglish", ein tolles Video !