Willkommen zurück zu Lektion 4 in unserem Python von Scratch Serie. Dieses Tutorial setzt voraus, dass Sie sich mit Variablen, Datentypen, Funktionen und Druckausgaben auskennen. Wenn Sie nicht auf dem neuesten Stand sind, schauen Sie sich die drei vorherigen Artikel der Serie an.
Heute befassen wir uns mit dem Thema Object Oriented Programming (OOP). OOP ist eine sehr effektive Methode, Ihren Code zu organisieren, und ein solides Verständnis der dahinter stehenden Konzepte kann Ihnen wirklich dabei helfen, das Beste aus Ihrem Programm herauszuholen.
Python ist in erster Linie als objektorientierte Programmiersprache konzipiert - was aber eigentlich "objektorientiert" ist?
Es gibt verschiedene Definitionen für den Begriff, und Sie könnten buchstäblich stundenlang reden und versuchen, die komplizierten Besonderheiten und Feinheiten sowie die Unterschiede bei der Implementierung zu erklären, aber ich versuche, einen schnellen Überblick zu geben.
Objektorientiertes Programmieren ist im Allgemeinen das Konzept, dass bei der Programmierung die Objekte, die wir bearbeiten, wichtiger sind als die Logik, die zum Manipulieren dieser Objekte benötigt wird. Traditionell wurde ein Programm als Rezept betrachtet - eine Reihe von Anweisungen, die Sie von Anfang bis Ende befolgen, um eine Aufgabe abzuschließen. Das kann immer noch zutreffen, und für viele einfache Programme ist das alles, was benötigt wird. Dieser Ansatz wird manchmal als prozedurale Programmierung bezeichnet.
OOP stellt Objekte in den Mittelpunkt des Prozesses.
Auf der anderen Seite, da Programme immer komplexer und komplizierter werden, wird die Logik, die benötigt wird, um sie auf rein prozedurale Weise zu schreiben, immer mehr verdreht und schwer zu verstehen. Oft helfen dabei objektorientierte Ansätze.
Wenn wir über objektorientierte Ansätze sprechen, stellen wir die Objekte in den Mittelpunkt des Prozesses, anstatt sie einfach als notwendige Informationsbehälter im Rahmen unserer Verfahrensanweisungen zu verwenden. Zuerst definieren wir die Objekte, die wir manipulieren möchten, und wie sie miteinander in Beziehung stehen, und beginnen dann, es mit Logik zu verfeinern, damit das Programm tatsächlich funktioniert.
Wenn ich über 'Objekte' spreche, kann ich über alle möglichen Dinge sprechen. Ein "Objekt" kann eine Person (wie durch Eigenschaften wie Name, Alter, Adresse usw. definiert) oder eine Firma (wie etwa durch die Anzahl der Angestellten usw.) oder auch etwas abstrakteres wie ein Schaltfläche in einer Computerschnittstelle.
In dieser Einführung werden wir nicht alle Konzepte dieses Themas behandeln, da wir die ganze Nacht hier wären, aber am Ende des Tutorials hoffe ich, dass Sie ein solides Verständnis der Prinzipien haben, die Sie benötigen um sofort mit der Verwendung einiger einfacher objektorientierter Techniken in Ihren Python-Programmen zu beginnen. Noch besser, diese Konzepte sind in vielen Programmierumgebungen ziemlich ähnlich. Das Wissen überträgt sich sehr gut von Sprache zu Sprache.
Ich habe bereits erwähnt, dass wir als Erstes bei einem OOP-Ansatz die Objekte definieren müssen, die wir verwenden werden. Die Art und Weise, wie wir dies tun, besteht darin, zuerst die Eigenschaften zu definieren, die sie über eine Klasse besitzt. Sie können sich eine Klasse als eine Art Vorlage vorstellen. eine Anleitung, wie ein Objekt strukturiert werden soll. Jedes Objekt gehört zu einer Klasse und erbt die Eigenschaften dieser Klasse, wirkt jedoch individuell auf die anderen Objekte dieser Klasse ein.
Ein Objekt wird manchmal als "Instanz" einer Klasse bezeichnet.
Ein einfaches Beispiel ist, dass Sie eine Klasse mit dem Namen "Person" haben, die beispielsweise ein Alter und eine Namenseigenschaft enthält, und eine Instanz dieser Klasse (ein Objekt) wäre eine einzelne Person. Diese Person könnte einen Namen haben? Andy? und im Alter von 23 Jahren, aber Sie könnten gleichzeitig eine andere Person haben, die zu derselben Klasse mit dem Namen "Lucy" gehört. und ein Alter von 18 Jahren.
Es ist schwer zu verstehen, ohne es in der Praxis zu sehen, also lassen Sie uns den eigentlichen Code zum Laufen bringen.
Um eine Klasse zu definieren, verwenden wir auf typische einfache Python-Art das Wort "class", gefolgt vom Namen Ihrer neuen Klasse. Ich werde hier eine neue Klasse machen, die "pet" heißt. Wir verwenden nach dem Namen einen Doppelpunkt, und alles, was in der Klassendefinition enthalten ist, wird eingerückt. Bei einer Klasse gibt es jedoch keine Klammern:
Klassenhaustier:
Jetzt haben wir eine Klasse, aber ohne etwas ist es nutzlos. Lassen Sie uns zunächst einige Eigenschaften angeben. Dazu definieren Sie einfach einige Variablen innerhalb der Klasse - ich werde mit der Anzahl der Abschnitte beginnen, mit denen ich beginnen möchte. Wie üblich sollten Sie Ihre Variablen immer so benennen, dass sie leicht zu erkennen sind. Lassen Sie uns originell sein und nennen es 'number_of_legs'. Wir müssen einen Wert definieren oder wir erhalten einen Fehler. Ich verwende hier 0 (es ist in diesem Fall nicht wichtig, da die Anzahl der Beine für jede Klasse der Klasse spezifisch ist - ein Fisch hat nicht die gleiche Anzahl an Beinen wie ein Hund oder eine Ente). usw. - also müssen wir diesen Wert für jedes Objekt trotzdem ändern).
Klasse pet: number_of_legs = 0
Eine Klasse allein kann nicht direkt manipuliert werden. Zuerst müssen wir eine Instanz der Klasse erstellen, um damit zu spielen. Wir können diese Instanz in einer Variablen speichern. Außerhalb der Klasse (ohne Einrückung) erstellen wir eine Instanz der Klasse und speichern sie in der Variablen 'doug'. Um eine neue Instanz einer Klasse zu erstellen, geben Sie einfach den Namen der Klasse und dann ein Paar Klammern ein. An diesem Punkt müssen Sie sich nicht um die Klammern kümmern, aber später werden Sie feststellen, dass sie vorhanden sind, da es wie bei einer Funktion eine Möglichkeit gibt, eine Variable zur Verwendung durch die Klasse beim ersten Erstellen der Instanz zu übergeben.
Eine Klasse allein kann nicht direkt manipuliert werden.
Klasse pet: number_of_legs = 0 doug = pet ()
Nun, da wir eine Instanz einer Klasse haben, wie können wir auf ihre Eigenschaften zugreifen und diese bearbeiten? Um auf eine Eigenschaft eines Objekts zu verweisen, müssen wir zuerst Python mitteilen, über welches Objekt (oder über welche Instanz einer Klasse) wir sprechen. Wir beginnen mit 'doug'. Dann schreiben wir eine Periode, um darauf hinzuweisen, dass wir auf etwas beziehen, das in unserer Doug-Instanz enthalten ist. Nach dem Zeitraum fügen wir den Namen unserer Variablen hinzu. Wenn wir auf das zugreifen number_of_legs
Variable wird es so aussehen:
doug.number_of_legs
Wir können das jetzt genau so behandeln, wie wir jede andere Variable behandeln würden - hier gehe ich davon aus, dass doug ein Hund ist und dieser Variablen den Wert 4 geben wird.
Um auf diese Variable zuzugreifen, verwenden wir sie wieder genau so, wie wir jede andere Variable behandeln würden doug.number_of_legs
Eigenschaft anstelle des normalen Variablennamens. Lassen Sie uns in einer Zeile drucken, wie viele Beine Doug hat, damit wir zeigen können, dass es so funktioniert, wie es sollte:
class pet: number_of_legs = 0 doug = pet () doug.number_of_legs = 4 print "Doug hat% s Beine." % doug.number_of_legs
Wenn Sie den obigen Code ausführen, sehen Sie, dass er für uns ausgedruckt ist. Sie definierte unsere 'pet'-Klasse, erstellte eine neue Instanz dieser Klasse und speicherte sie in der Variablen' doug '. Anschließend wurde ihr der Wert 4 zugewiesen number_of_legs
Variable, die es von seiner Klasse geerbt hat.
An diesem sehr vereinfachten Beispiel können Sie sehen, wie Sie mit dem Aufbau schöner, modularer Datenstrukturen beginnen können, die klar und einfach zu verwenden sind und die Skalierung ziemlich gut beginnt.
Okay, das sind also die Grundlagen von Klassen und Objekten, aber im Moment können Klassen nur wirklich als Datenstrukturen oder Container für Variablen verwendet werden. Das ist alles gut und schön, aber wenn wir mit den von uns manipulierten Daten komplexere Aufgaben ausführen wollen, müssen wir eine Art Logik in diese Objekte einführen. Wir machen das mit Methoden.
Methoden sind im Wesentlichen Funktionen, die in einer Klasse enthalten sind. Sie definieren eine genauso wie eine Funktion, der Unterschied besteht jedoch darin, dass Sie sie in eine Klasse einfügen, die zu dieser Klasse gehört. Wenn Sie diese Methode jemals aufrufen möchten, müssen Sie zunächst ein Objekt dieser Klasse referenzieren, genau wie die Variablen, die wir zuvor betrachtet haben.
Methoden sind im Wesentlichen Funktionen, die in einer Klasse enthalten sind.
Ich werde hier ein kurzes Beispiel in unsere Klasse für Haustiere schreiben, um dies zu demonstrieren. Lassen Sie uns eine Methode namens "sleep" erstellen, die beim ersten Aufruf eine Nachricht ausgibt. Genau wie bei einer Funktion werde ich 'def' für 'define' setzen und dann den Namen der Methode schreiben, die ich erstellen möchte. Dann setzen wir unsere Klammern und das Semikolon und beginnen dann eine neue Zeile. Wie üblich wird alles, was in dieser Methode enthalten ist, um eine zusätzliche Ebene eingerückt.
Nun gibt es einen weiteren Unterschied zwischen einer Methode und einer Funktion: Eine Methode muss immer ein Argument haben, das als "Selbst" zwischen den Klammern bezeichnet wird. Wenn Python eine Methode aufruft, übergibt es als erstes Argument das aktuelle Objekt an diese Methode. Mit anderen Worten, wenn wir anrufen doug.sleep ()
, Python wird eigentlich das Objekt 'doug' als Argument an die sleep-Methode übergeben.
Wir werden sehen, warum das später ist, aber im Moment müssen Sie wissen, dass Sie bei einer Methode immer zuerst ein Argument namens "self" in die Liste aufnehmen müssen (wenn Sie weitere Argumente hinzufügen möchten, können Sie sie hinzufügen.) danach, genau so, als würden Sie mehrere Argumente an eine Funktion übergeben. Wenn Sie dieses Argument nicht angeben, wird beim Ausführen des Codes ein Fehler ausgegeben, da Python ein Argument (dieses 'self'-Objekt) übergeben hat und die Methode sagt:' Hey, Mann, Ich nehme keine Argumente an, wovon redest du? Es ist das gleiche, als ob Sie versucht hätten, ein Argument an eine Funktion zu übergeben, die keine Argumente akzeptiert.
Also hier ist was wir bis jetzt haben:
Klasse pet: number_of_legs = 0 def sleep (self): doug = pet ()
In dieser Methode schreiben wir eine Print-Anweisung wie folgt:
Klasse pet: number_of_legs = 0 def sleep (self): print "zzz" doug = pet ()
Wenn wir diese Methode verwenden möchten, verwenden wir einfach eine Instanz der Klasse pet, um darauf zu verweisen. Genau wie das number_of_legs
Variable schreiben wir den Namen der Instanz (wir haben einen Namen namens doug), dann einen Punkt, dann den Namen der Methode einschließlich Klammern. Beachten Sie, dass wir den Ruhezustand ohne Argumente aufrufen, aber Python wird dieses Argument selbst hinzufügen, sodass am Ende die richtige Anzahl an Argumenten angezeigt wird.
Klasse pet: number_of_legs = 0 def sleep (self): print "zzz" doug = pet () doug.sleep ()
Wenn Sie diesen Code ausführen, sollten Sie sehen, dass die von uns geschriebene Nachricht gedruckt wird.
Wie wäre es also, wenn wir eine neue Methode schreiben, um auszudrucken, wie viele Beine das Haustier hat, um zu zeigen, wie Sie mit den Daten anfangen können, die Daten innerhalb der Klasse zu bearbeiten, und um zu zeigen, warum wir dieses verwirrende "Ich" verwenden müssen? Streit. Lass uns eine neue Methode machen, genannt 'count_legs
'.
Hier kommt das 'Selbst' Argument an. Erinnern Sie sich, als wir zugegriffen haben number_of_legs
von außerhalb der Klasse und wir mussten 'doug.number_of_legs' anstelle von 'number_of_legs' verwenden? Das gleiche Prinzip gilt. Wenn wir wissen wollen, was in dieser Variablen enthalten ist, müssen wir darauf verweisen, indem wir zuerst die Instanz angeben, die diese Variable enthält.
Wir wissen jedoch nicht, wie die Instanz aufgerufen wird, wenn wir die Klasse schreiben. Daher umgehen wir dies mit der 'self'-Variablen. 'self' ist nur ein Verweis auf das Objekt, das gerade bearbeitet wird. Um auf eine Variable in der aktuellen Klasse zuzugreifen, müssen Sie sie nur mit 'self' und dann mit einem Punkt voranstellen:
class pet: number_of_legs = 0 def sleep (self): print "zzz" def count_legs (self): print "Ich habe% s Beine"% self.number_of_legs doug = pet () doug.number_of_legs = 4 doug.count_legs ()
In der Praxis bedeutet dies, dass, wo immer Sie "self" in Ihre Methode schreiben, wenn Sie die Methode ausführen, die self durch den Namen des Objekts ersetzt wird. Wenn Sie also "doug.count_legs ()" aufrufen, wird "self" verwendet ersetzt durch 'doug'. Um zu zeigen, wie dies mit mehreren Instanzen funktioniert, fügen Sie eine zweite Instanz hinzu, die ein anderes Haustier namens "nemo" darstellt:
class pet: number_of_legs = 0 def sleep (self): print "zzz" def count_legs (self): print "Ich habe% s Beine"% self.number_of_legs doug = pet () doug.number_of_legs = 4 doug.count_legs () nemo = pet () nemo.number_of_legs = 0 nemo.count_legs ()
Dies gibt eine Nachricht für 4 und dann 0 Beine aus, genau wie wir es wollten, denn wenn wir 'nemo.count_legs () aufrufen, wird' das 'Selbst' durch 'Nemo' anstelle von 'Doug' ersetzt..
Auf diese Weise wird unsere Methode genau wie beabsichtigt ausgeführt, da sich der 'Selbst'-Verweis je nach Kontext dynamisch ändert und uns erlaubt, die Daten nur innerhalb des aktuellen Objekts zu bearbeiten.
Die wichtigsten Dinge, die Sie bei Methoden beachten sollten, sind, dass sie genau wie Funktionen aussehen, mit der Ausnahme, dass das erste Argument 'self' sein muss und dass für den Verweis auf eine interne Variable der Variablenname mit 'self' vorangestellt werden muss..
Nur als Hinweis: Sie können tatsächlich einen beliebigen Namen anstelle von "self" für Ihre Methoden verwenden. -Die Methoden hier würden genauso gut funktionieren, wenn wir die Variable 'self' in ein beliebiges Wort umbenennen. Die Verwendung des Namens 'self' ist einfach eine Konvention, die für Python-Programmierer nützlich ist, da sie den Code viel standardisierter und leichter verständlich macht, selbst wenn er von anderen geschrieben wurde. Mein Rat wäre, sich an die Konventionen zu halten.
Nun, da wir uns mit den Grundlagen beschäftigt haben, wollen wir uns einige fortgeschrittenere Funktionen von Klassen ansehen und wie sie dazu beitragen können, die Programmierung einfacher zu strukturieren.
Das nächste, worüber wir sprechen werden, ist Vererbung. Wie der Name schon vermuten lässt, ist Vererbung der Vorgang, bei dem eine neue Klasse um eine übergeordnete Klasse herum angelegt wird und die neue Klasse die Funktionen der übergeordneten Klasse erben kann. Die neue Klasse kann alle Methoden und Variablen der übergeordneten Klasse entnehmen (oft als "Basisklasse" bezeichnet)..
Vererbung ist der Prozess, bei dem eine neue Klasse auf Basis einer übergeordneten Klasse erstellt wird.
Lassen Sie uns unser Haustierbeispiel erweitern, um zu sehen, wie dies nützlich sein kann. Wenn wir 'pet' als übergeordnete Klasse verwenden, können wir eine untergeordnete Klasse erstellen, die von der pet-Klasse übernommen wurde. Die Kinderklasse könnte etwas wie "Hund" oder "Fisch" sein - etwas, das immer noch ein "Haustier" ist, aber spezifischer ist. Ein Hund ist ein Haustier und tut dasselbe wie alle Haustiere - er isst und schläft und hat ein Alter und eine Reihe von Beinen - aber er tut andere Dinge, die spezifisch für einen Hund sind oder zumindest spezifischer sind als ein Haustier zu sein: Hunde haben Fell, aber nicht alle Haustiere. Ein Hund könnte bellen oder einen Stock holen, aber nicht alle Haustiere würden dies tun.
Um auf den Punkt zurückzukommen, sagen wir, wir wollten in unserem Programm eine Klasse bilden, um einen Hund darzustellen. Wir könnten Vererbung verwenden, um die in "Pets" enthaltenen Methoden und Variablen zu erben, sodass unser Hund zusätzlich zu all den hundespezifischen Dingen, die wir speichern oder tun könnten, eine "numberOf Legs" und die Fähigkeit "schlafen" kann.
Nun fragen Sie sich vielleicht, warum wir diese Methoden und Variablen nicht in die Hundeklasse aufnehmen und die Tierklasse vollständig loswerden? Nun, die Vererbung bietet uns gegenüber diesem Ansatz zwei entscheidende Vorteile: Erstens, wenn wir ein Objekt wünschen, das ein Haustier ist, aber kein Hund - ein generisches Haustier, wenn Sie so wollen - können wir das immer noch. Zweitens, vielleicht möchten wir später einen zweiten Haustyp hinzufügen - vielleicht einen Fisch. Wir können diese zweite Klasse auch von pet erben lassen, so dass beide Klassen alles in pet gemeinsam nutzen können, aber gleichzeitig eigene, spezifischere Methoden und Variablen haben, die nur für diesen Objekttyp gelten.
Wir werden hier in der Theorie ein bisschen verklemmt, also schreiben wir etwas, um es etwas klarer zu machen. Zuerst schreiben wir eine neue Klasse mit dem Namen 'dog', aber diesmal werden zwischen dem Klassennamen und dem Doppelpunkt einige Klammern eingefügt, und in diese werden wir den Namen schreiben von der Klasse, von der wir erben wollen, als ob wir dieser neuen Klasse ein Argument übergeben würden, als würden wir eine Funktion haben.
Als Nächstes geben wir dieser Klasse eine einfache Methode, um zu zeigen, wie sie funktioniert. Ich werde ein 'hinzufügenBorke
'Methode, die' woof 'drucken wird:
class pet: number_of_legs = 0 def sleep (self): print "zzz" def count_legs (self): print "Ich habe% s Beine"% self.number_of_legs class dog (pet): def bark (self): print "Woof"
Schauen wir uns also an, was passiert, wenn wir eine Klasse dieser Klasse erstellen. Ich werde unseren neuen Hund wieder "doug" nennen. Nun, wenn wir anrufen doug.bark ()
:
class pet: number_of_legs = 0 def sleep (self): print "zzz" def count_legs (self): print "Ich habe% s Beine"% self.number_of_legs class dog (pet): def bark (self): print "Woof" doug = dog () doug.bark ()
Wie erwartet bellt Doug. Das ist großartig, aber wir haben noch nichts Neues gesehen - nur eine Klasse mit einer Methode. Was Vererbung für uns getan hat, ist jedoch, alle Haustierfunktionen und -variablen durch unser 'doug'-Objekt verfügbar zu machen. Wenn ich also so etwas mache:
class pet: number_of_legs = 0 def sleep (self): print "zzz" def count_legs (self): print "Ich habe% s Beine"% self.number_of_legs class dog (pet): def bark (self): print "Woof" doug = dog () doug.sleep ()
Dann wird auch die Schlafmethode korrekt ausgeführt. Tatsächlich gehört unser Doug-Objekt sowohl zur Klasse „Haustier“ als auch zur Klasse „Hund“. Um sicherzustellen, dass die Variablen dasselbe tun wie die Methoden, versuchen wir Folgendes:
class pet: number_of_legs = 0 def sleep (self): print "zzz" def count_legs (self): print "Ich habe% s Beine"% self.number_of_legs class dog (pet): def bark (self): print "Woof" doug = dog () doug.number_of_legs = 4 doug.count_legs ()
Sie sehen, dass doug genau wie zuvor wirkt und zeigt, dass unsere Variablen vererbt werden. Unsere neue Kindklasse ist einfach eine spezialisierte Version der übergeordneten, mit einigen zusätzlichen Funktionen, die jedoch alle vorherigen Funktionen beibehalten.
So haben Sie es, eine schnelle Einführung in die objektorientierte Programmierung. Bleiben Sie dran für die nächste Folge dieser Serie, in der wir mit Python im Web arbeiten werden!