Wie Objekte repräsentiert werden

PythonPythonBeginner
Jetzt üben

This tutorial is from open-source community. Access the source code

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

In diesem Lab werden Sie lernen, wie Python-Objekte intern repräsentiert werden, und die Mechanismen der Attributzuweisung und -suche verstehen. Diese Konzepte sind grundlegend für das Verständnis, wie Python Daten und Verhalten innerhalb von Objekten verwaltet.

Zusätzlich werden Sie die Beziehung zwischen Klassen und Instanzen untersuchen und die Rolle von Klassendefinitionen in der objektorientierten Programmierung betrachten. Dieses Wissen wird Ihr Verständnis der objektorientierten Eigenschaften von Python verbessern.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/ObjectOrientedProgrammingGroup(["Object-Oriented Programming"]) python/ObjectOrientedProgrammingGroup -.-> python/classes_objects("Classes and Objects") python/ObjectOrientedProgrammingGroup -.-> python/constructor("Constructor") subgraph Lab Skills python/classes_objects -.-> lab-132499{{"Wie Objekte repräsentiert werden"}} python/constructor -.-> lab-132499{{"Wie Objekte repräsentiert werden"}} end

Erstellen einer einfachen Aktienklasse

In diesem Schritt werden wir eine einfache Klasse erstellen, um eine Aktie darzustellen. Das Verständnis, wie man Klassen erstellt, ist in Python grundlegend, da es uns ermöglicht, reale Objekte und ihr Verhalten zu modellieren. Diese einfache Aktienklasse wird unser Ausgangspunkt sein, um zu untersuchen, wie Python-Objekte intern funktionieren.

Um zu beginnen, müssen wir eine Python interaktive Shell öffnen. Die Python interaktive Shell ist ein ausgezeichneter Ort, um mit Python-Code zu experimentieren. Sie können Python-Befehle nacheinander eingeben und ausführen. Um sie zu öffnen, geben Sie den folgenden Befehl in der Kommandozeile ein:

python3

Sobald Sie den Befehl eingegeben haben, sehen Sie die Python-Eingabeaufforderung (>>>). Dies zeigt an, dass Sie jetzt in der Python interaktiven Shell sind und mit dem Schreiben von Python-Code beginnen können.

Jetzt definieren wir eine SimpleStock-Klasse. Eine Klasse in Python ist wie ein Bauplan für die Erstellung von Objekten. Sie definiert die Attribute (Daten) und Methoden (Funktionen), die die Objekte dieser Klasse haben werden. So definieren Sie die SimpleStock-Klasse mit den erforderlichen Attributen und Methoden:

>>> class SimpleStock:
...     def __init__(self, name, shares, price):
...         self.name = name
...         self.shares = shares
...         self.price = price
...     def cost(self):
...         return self.shares * self.price
...

Im obigen Code ist die __init__-Methode eine spezielle Methode in Python-Klassen. Sie wird Konstruktor genannt und wird verwendet, um die Attribute eines Objekts zu initialisieren, wenn ein Objekt erstellt wird. Der Parameter self bezieht sich auf die Instanz der Klasse, die erstellt wird. Die cost-Methode berechnet die Gesamtkosten der Aktien, indem sie die Anzahl der Aktien mit dem Preis pro Aktie multipliziert.

Nachdem wir die Klasse definiert haben, können wir Instanzen der SimpleStock-Klasse erstellen. Eine Instanz ist ein tatsächliches Objekt, das aus dem Klassen-Bauplan erstellt wird. Erstellen wir zwei Instanzen, um verschiedene Aktien darzustellen:

>>> goog = SimpleStock('GOOG', 100, 490.10)
>>> ibm = SimpleStock('IBM', 50, 91.23)

Diese Instanzen repräsentieren 100 Aktien der Google-Aktie zu einem Preis von 490,10 US-Dollar pro Aktie und 50 Aktien der IBM-Aktie zu einem Preis von 91,23 US-Dollar pro Aktie. Jede Instanz hat ihre eigene Menge an Attributwerten.

Lassen Sie uns überprüfen, ob unsere Instanzen ordnungsgemäß funktionieren. Wir können dies tun, indem wir ihre Attribute überprüfen und ihre Kosten berechnen. Dies wird uns helfen zu bestätigen, dass die Klasse und ihre Methoden wie erwartet funktionieren.

>>> goog.name
'GOOG'
>>> goog.shares
100
>>> goog.price
490.1
>>> goog.cost()
49010.0
>>> ibm.cost()
4561.5

Die cost()-Methode multipliziert die Anzahl der Aktien mit dem Preis pro Aktie, um die Gesamtkosten für das Halten dieser Aktien zu berechnen. Durch das Ausführen dieser Befehle können wir sehen, dass die Instanzen die richtigen Attributwerte haben und dass die cost-Methode die Kosten korrekt berechnet.

Erkundung des internen Dictionaries von Objekten

In Python sind Objekte ein grundlegendes Konzept. Ein Objekt kann als ein Behälter angesehen werden, der Daten enthält und bestimmte Verhaltensweisen hat. Einer der interessanten Aspekte von Python-Objekten ist die Art und Weise, wie sie ihre Attribute speichern. Attribute sind wie Variablen, die zu einem Objekt gehören. Python speichert diese Attribute in einem speziellen Dictionary, auf das über das __dict__-Attribut zugegriffen werden kann. Dieses Dictionary ist ein interner Bestandteil des Objekts, und hier hält Python alle Daten, die mit diesem Objekt verbunden sind, fest.

Schauen wir uns diese interne Struktur genauer an, indem wir unsere SimpleStock-Instanzen verwenden. In Python ist eine Instanz ein individuelles Objekt, das aus einer Klasse erstellt wird. Wenn beispielsweise SimpleStock eine Klasse ist, sind goog und ibm Instanzen dieser Klasse.

Um das interne Dictionary dieser Instanzen zu sehen, können wir die Python interaktive Shell verwenden. Die Python interaktive Shell ist ein ausgezeichnetes Werkzeug, um schnell Code zu testen und die Ergebnisse zu sehen. Geben Sie in der Python interaktiven Shell die folgenden Befehle ein, um das __dict__-Attribut unserer Instanzen zu untersuchen:

>>> goog.__dict__
{'name': 'GOOG', 'shares': 100, 'price': 490.1}
>>> ibm.__dict__
{'name': 'IBM', 'shares': 50, 'price': 91.23}

Wenn Sie diese Befehle ausführen, zeigt die Ausgabe, dass jede Instanz ihr eigenes internes Dictionary hat. Dieses Dictionary enthält alle Instanzattribute. Beispielsweise werden im goog-Objekt die Attribute name, shares und price zusammen mit ihren entsprechenden Werten im Dictionary gespeichert. So implementiert Python Objektattribute im Hintergrund. Jedes Objekt hat ein privates Dictionary, das alle seine Attribute enthält.

Es ist wichtig zu verstehen, was das __dict__-Attribut über die interne Implementierung unserer Objekte verrät:

  1. Die Schlüssel im Dictionary entsprechen den Attributnamen. Beispielsweise entspricht im goog-Objekt der Schlüssel 'name' dem name-Attribut des Objekts.
  2. Die Werte im Dictionary sind die Attributwerte. Der Wert 'GOOG' ist also der Wert des name-Attributs für die goog-Instanz.
  3. Jede Instanz hat ihr eigenes separates __dict__. Dies bedeutet, dass die Attribute einer Instanz unabhängig von den Attributen einer anderen Instanz sind. Beispielsweise kann das shares-Attribut der goog-Instanz von dem shares-Attribut der ibm-Instanz unterschiedlich sein.

Dieser auf einem Dictionary basierende Ansatz ermöglicht es Python, mit Objekten sehr flexibel zu sein. Wie wir im nächsten Schritt sehen werden, können wir diese Flexibilität nutzen, um Objektattribute auf verschiedene Weise zu ändern und darauf zuzugreifen.

Hinzufügen und Ändern von Objektattributen

In Python werden Objekte auf der Grundlage von Dictionaries implementiert. Diese Implementierung verleiht Python eine hohe Flexibilität bei der Behandlung von Objektattributen. Im Gegensatz zu einigen anderen Programmiersprachen beschränkt Python die Attribute eines Objekts nicht nur auf diejenigen, die in seiner Klasse definiert sind. Das bedeutet, dass Sie einem Objekt jederzeit neue Attribute hinzufügen können, auch nachdem das Objekt erstellt wurde.

Lassen Sie uns diese Flexibilität erkunden, indem wir einem unserer Objekte ein neues Attribut hinzufügen. Nehmen wir an, wir haben eine Instanz namens goog einer Klasse. Wir fügen ihr ein date-Attribut hinzu:

>>> goog.date = "6/11/2007"
>>> goog.__dict__
{'name': 'GOOG', 'shares': 100, 'price': 490.1, 'date': '6/11/2007'}

Hier haben wir ein neues Attribut date zur goog-Instanz hinzugefügt. Beachten Sie, dass dieses date-Attribut in der SimpleStock-Klasse nicht definiert war. Dieses neue Attribut existiert nur in der goog-Instanz. Um dies zu bestätigen, überprüfen wir die ibm-Instanz:

>>> ibm.__dict__
{'name': 'IBM', 'shares': 50, 'price': 91.23}
>>> hasattr(ibm, 'date')
False

Wie wir sehen können, hat die ibm-Instanz kein date-Attribut. Dies zeigt drei wichtige Eigenschaften von Python-Objekten:

  1. Jede Instanz hat ihre eigene eindeutige Menge an Attributen.
  2. Attributen können einem Objekt nach seiner Erstellung hinzugefügt werden.
  3. Das Hinzufügen eines Attributs zu einer Instanz wirkt sich nicht auf andere Instanzen aus.

Jetzt versuchen wir eine andere Möglichkeit, ein Attribut hinzuzufügen. Anstatt die Punktnotation zu verwenden, manipulieren wir direkt das zugrunde liegende Dictionary des Objekts. In Python hat jedes Objekt ein spezielles Attribut __dict__, das alle seine Attribute als Schlüssel-Wert-Paare speichert.

>>> goog.__dict__['time'] = '9:45am'
>>> goog.time
'9:45am'
>>> goog.__dict__
{'name': 'GOOG', 'shares': 100, 'price': 490.1, 'date': '6/11/2007', 'time': '9:45am'}

Indem wir das __dict__-Dictionary direkt modifizieren, haben wir ein neues Attribut time zur goog-Instanz hinzugefügt. Wenn wir auf goog.time zugreifen, sucht Python nach dem 'time'-Schlüssel im __dict__-Dictionary und gibt den entsprechenden Wert zurück.

Diese Beispiele zeigen, dass Python-Objekte im Wesentlichen Dictionaries mit einigen zusätzlichen Funktionen sind. Die Flexibilität von Python-Objekten ermöglicht dynamische Modifikationen, was in der Programmierung sehr leistungsstark und praktisch ist.

Verständnis der Beziehung zwischen Klassen und Instanzen

Nun werden wir untersuchen, wie Klassen und Instanzen in Python zusammenhängen und wie die Methodensuche funktioniert. Dies ist ein wichtiges Konzept, da es Ihnen hilft zu verstehen, wie Python Methoden und Attribute findet und verwendet, wenn Sie mit Objekten arbeiten.

Zunächst überprüfen wir, zu welcher Klasse unsere Instanzen gehören. Die Kenntnis der Klasse einer Instanz ist von entscheidender Bedeutung, da sie uns sagt, wo Python nach Methoden und Attributen sucht, die sich auf diese Instanz beziehen.

>>> goog.__class__
<class '__main__.SimpleStock'>
>>> ibm.__class__
<class '__main__.SimpleStock'>

Beide Instanzen haben eine Referenz zurück zur SimpleStock-Klasse. Diese Referenz ist wie ein Zeiger, den Python verwendet, wenn es Methoden suchen muss. Wenn Sie eine Methode auf einer Instanz aufrufen, verwendet Python diese Referenz, um die entsprechende Methodendefinition zu finden.

Wenn Sie eine Methode auf einer Instanz aufrufen, folgt Python diesen Schritten:

  1. Es sucht nach dem Attribut im __dict__ der Instanz. Das __dict__ einer Instanz ist wie ein Speicherbereich, in dem alle instanzspezifischen Attribute gespeichert sind.
  2. Wenn es nicht gefunden wird, überprüft es das __dict__ der Klasse. Das __dict__ der Klasse speichert alle Attribute und Methoden, die allen Instanzen dieser Klasse gemeinsam sind.
  3. Wenn es in der Klasse gefunden wird, gibt es dieses Attribut zurück.

Lassen Sie uns dies in Aktion sehen. Zunächst überprüfen wir, ob die cost-Methode nicht in den Instanz-Dictionaries enthalten ist. Dieser Schritt hilft uns zu verstehen, dass die cost-Methode nicht für jede Instanz spezifisch ist, sondern auf Klassenebene definiert ist.

>>> 'cost' in goog.__dict__
False
>>> 'cost' in ibm.__dict__
False

Woher kommt also die cost-Methode? Lassen Sie uns die Klasse überprüfen. Indem wir uns das __dict__ der Klasse ansehen, können wir herausfinden, wo die cost-Methode definiert ist.

>>> SimpleStock.__dict__['cost']
<function SimpleStock.cost at 0x7f...>

Die Methode ist in der Klasse definiert, nicht in den Instanzen. Wenn Sie goog.cost() aufrufen, findet Python cost nicht in goog.__dict__, sucht also in SimpleStock.__dict__ und findet es dort.

Sie können die Methode tatsächlich direkt aus dem Klassen-Dictionary aufrufen, indem Sie die Instanz als erstes Argument übergeben (das dann self wird). Dies zeigt, wie Python intern Methoden aufruft, wenn Sie die normale Syntax instanz.methode() verwenden.

>>> SimpleStock.__dict__['cost'](goog)
49010.0
>>> SimpleStock.__dict__['cost'](ibm)
4561.5

Das ist im Wesentlichen, was Python im Hintergrund macht, wenn Sie goog.cost() aufrufen.

Nun fügen wir ein Klassenattribut hinzu. Klassenattribute werden von allen Instanzen geteilt. Das bedeutet, dass alle Instanzen der Klasse auf dieses Attribut zugreifen können und es nur einmal auf Klassenebene gespeichert wird.

>>> SimpleStock.exchange = 'NASDAQ'
>>> goog.exchange
'NASDAQ'
>>> ibm.exchange
'NASDAQ'

Beide Instanzen können auf das exchange-Attribut zugreifen, aber es ist nicht in ihren individuellen Dictionaries gespeichert. Lassen Sie uns dies überprüfen, indem wir die Instanz- und Klassen-Dictionaries überprüfen.

>>> 'exchange' in goog.__dict__
False
>>> 'exchange' in SimpleStock.__dict__
True
>>> SimpleStock.__dict__['exchange']
'NASDAQ'

Dies zeigt, dass:

  1. Klassenattribute von allen Instanzen geteilt werden. Alle Instanzen können auf dasselbe Klassenattribut zugreifen, ohne ihre eigene Kopie zu haben.
  2. Python überprüft zunächst das Instanz-Dictionary und dann das Klassen-Dictionary. Dies ist die Reihenfolge, in der Python nach Attributen sucht, wenn Sie versuchen, auf sie in einer Instanz zuzugreifen.
  3. Klassen fungieren als Repository für geteilte Daten und Verhalten (Methoden). Die Klasse speichert alle gemeinsamen Attribute und Methoden, die von allen ihren Instanzen verwendet werden können.

Wenn wir ein Instanzattribut mit demselben Namen ändern, überdeckt es das Klassenattribut. Das bedeutet, dass wenn Sie auf das Attribut in dieser Instanz zugreifen, Python den instanzspezifischen Wert anstelle des Werts auf Klassenebene verwenden wird.

>>> ibm.exchange = 'NYSE'
>>> ibm.exchange
'NYSE'
>>> goog.exchange  ## Noch immer das Klassenattribut
'NASDAQ'
>>> ibm.__dict__['exchange']
'NYSE'

Jetzt hat ibm sein eigenes exchange-Attribut, das das Klassenattribut überdeckt, während goog weiterhin das Klassenattribut verwendet.

Zusammenfassung

In diesem Lab haben Sie die internen Funktionsweisen von Pythons Objektsystem und mehrere Schlüsselkonzepte kennengelernt. Zunächst speichern Python-Objekte Attribute in einem Dictionary, auf das über das __dict__-Attribut zugegriffen werden kann, was eine hohe Flexibilität bietet. Zweitens haben Sie verstanden, wie die Zuweisung und Suche von Attributen funktionieren, einschließlich der dynamischen Hinzufügung von Attributen und der Reihenfolge der Attributüberprüfung.

Darüber hinaus haben Sie die Beziehung zwischen Klassen und Instanzen untersucht. Klassen enthalten geteilte Daten und Verhalten, während Instanzen ihren eigenen Zustand aufrechterhalten. Sie haben auch entdeckt, wie Methodenaufrufe funktionieren, wobei Methoden in der Klasse über den self-Parameter auf Instanzen wirken. Das Verständnis dieser Konzepte vertieft Ihr Verständnis des objektorientierten Programmiermodells von Python und ist nützlich für das Debugging, das Design von Klassenhierarchien und das Erlernen fortgeschrittener Funktionen.