Neue Objekte mit Klassen erstellen

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 Abschnitt wird die class-Anweisung und die Idee der Erstellung neuer Objekte vorgestellt.

Objektorientierte Programmierung

Eine Programmiertechnik, bei der der Code als Sammlung von Objekten organisiert ist.

Ein Objekt besteht aus:

  • Daten. Attribute
  • Verhalten. Methoden, die als Funktionen auf das Objekt angewendet werden.

Sie haben bereits einige objektorientierte Konzepte in diesem Kurs verwendet.

Zum Beispiel beim Umgang mit einer Liste.

>>> nums = [1, 2, 3]
>>> nums.append(4)      ## Methode
>>> nums.insert(1,10)   ## Methode
>>> nums
[1, 10, 2, 3, 4]        ## Daten
>>>

nums ist eine Instanz einer Liste.

Methoden (append() und insert()) sind an die Instanz (nums) angehängt.

Die class-Anweisung

Verwenden Sie die class-Anweisung, um ein neues Objekt zu definieren.

class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.health = 100

    def move(self, dx, dy):
        self.x += dx
        self.y += dy

    def damage(self, pts):
        self.health -= pts

Kurz gesagt ist eine Klasse eine Menge von Funktionen, die verschiedene Operationen auf sogenannten Instanzen ausführen.

Instanzen

Instanzen sind die tatsächlichen Objekte, die Sie in Ihrem Programm manipulieren.

Sie werden erstellt, indem Sie die Klasse wie eine Funktion aufrufen.

>>> a = Player(2, 3)
>>> b = Player(10, 20)
>>>

a und b sind Instanzen von Player.

Betonen: Die class-Anweisung ist nur die Definition (sie macht nichts an sich). Ähnlich wie eine Funktionsdefinition.

Instanzdaten

Jede Instanz hat ihre eigenen lokalen Daten.

>>> a.x
2
>>> b.x
10

Diese Daten werden durch die __init__() initialisiert.

class Player:
    def __init__(self, x, y):
        ## Any value stored on `self` is instance data
        self.x = x
        self.y = y
        self.health = 100

Es gibt keine Beschränkungen für die Gesamtzahl oder den Typ der gespeicherten Attribute.

Instanzmethoden

Instanzmethoden sind Funktionen, die auf Instanzen eines Objekts angewendet werden.

class Player:
  ...
    ## `move` ist eine Methode
    def move(self, dx, dy):
        self.x += dx
        self.y += dy

Das Objekt selbst wird immer als erstes Argument übergeben.

>>> a.move(1, 2)

## passt `a` an `self`
## passt `1` an `dx`
## passt `2` an `dy`
def move(self, dx, dy):

Konventionell wird die Instanz self genannt. Der tatsächliche Name, der verwendet wird, ist jedoch unwichtig. Das Objekt wird immer als erstes Argument übergeben. Es ist lediglich der Python-Programmierstil, diesen Argument self zu nennen.

Klassenscopierung

Klassen definieren keinen Namensbereich.

class Player:
 ...
    def move(self, dx, dy):
        self.x += dx
        self.y += dy

    def left(self, amt):
        move(-amt, 0)       ## NEIN. Ruft eine globale `move`-Funktion auf
        self.move(-amt, 0)  ## JA. Ruft die Methode `move` aus oben auf.

Wenn Sie auf einer Instanz operieren möchten, verweisen Sie immer explizit darauf (z.B. self).

Ab diesem Satz von Übungen beginnen wir eine Reihe von Änderungen am vorhandenen Code aus vorherigen Abschnitten vorzunehmen. Es ist von entscheidender Bedeutung, dass Sie eine funktionierende Version von Übung 3.18 haben, um zu beginnen. Wenn Sie das nicht haben, arbeiten Sie bitte anhand des Lösungscodes, der sich im Verzeichnis Lösungen/3_18 befindet. Es ist in Ordnung, ihn zu kopieren.

Übung 4.1: Objekte als Datenstrukturen

Im Abschnitt 2 und 3 haben wir mit Daten gearbeitet, die als Tupel und Wörterbücher repräsentiert wurden. Beispielsweise könnte ein Aktienbesitz als Tupel wie folgt repräsentiert werden:

s = ('GOOG',100,490.10)

oder als Wörterbuch wie folgt:

s = { 'name'   : 'GOOG',
    'shares' : 100,
     'price'  : 490.10
}

Sie können sogar Funktionen zum Manipulieren solcher Daten schreiben. Beispielsweise:

def cost(s):
    return s['shares'] * s['price']

Allerdings kann es sein, dass Sie bei einem größeren Programm eine bessere Organisationsstruktur wünschen. Ein anderer Ansatz zur Datenrepräsentation wäre daher, eine Klasse zu definieren. Erstellen Sie eine Datei namens stock.py und definieren Sie eine Klasse Stock, die einen einzelnen Aktienbesitz repräsentiert. Lassen Sie die Instanzen von Stock die Attribute name, shares und price haben. Beispielsweise:

>>> import stock
>>> a = stock.Stock('GOOG',100,490.10)
>>> a.name
'GOOG'
>>> a.shares
100
>>> a.price
490.1
>>>

Erstellen Sie einige weitere Stock-Objekte und manipulieren Sie sie. Beispielsweise:

>>> b = stock.Stock('AAPL', 50, 122.34)
>>> c = stock.Stock('IBM', 75, 91.75)
>>> b.shares * b.price
6117.0
>>> c.shares * c.price
6881.25
>>> stocks = [a, b, c]
>>> stocks
[<stock.Stock object at 0x37d0b0>, <stock.Stock object at 0x37d110>, <stock.Stock object at 0x37d050>]
>>> for s in stocks:
     print(f'{s.name:>10s} {s.shares:>10d} {s.price:>10.2f}')

... schauen Sie sich die Ausgabe an...
>>>

Eines, das hier betont werden muss, ist, dass die Klasse Stock wie eine Fabrik für das Erstellen von Objektinstanzen funktioniert. Im Grunde rufen Sie sie wie eine Funktion auf und sie erstellt ein neues Objekt für Sie. Auch muss betont werden, dass jedes Objekt unterschiedlich ist - jedes hat seine eigenen Daten, die von anderen erstellten Objekten getrennt sind.

Ein von einer Klasse definiertes Objekt ähnelt etwas einem Wörterbuch - nur mit etwas unterschiedlicher Syntax. Beispielsweise schreiben Sie statt s['name'] oder s['price'] jetzt s.name und s.price.

✨ Lösung prüfen und üben

Übung 4.2: Hinzufügen einiger Methoden

Mit Klassen können Sie Funktionen an Ihre Objekte anfügen. Diese werden als Methoden bezeichnet und sind Funktionen, die auf den im Inneren eines Objekts gespeicherten Daten operieren. Fügen Sie eine cost()- und eine sell()-Methode zu Ihrem Stock-Objekt hinzu. Sie sollten so funktionieren:

>>> import stock
>>> s = stock.Stock('GOOG', 100, 490.10)
>>> s.cost()
49010.0
>>> s.shares
100
>>> s.sell(25)
>>> s.shares
75
>>> s.cost()
36757.5
>>>
✨ Lösung prüfen und üben

Übung 4.3: Erstellen einer Liste von Instanzen

Versuchen Sie die folgenden Schritte, um eine Liste von Stock-Instanzen aus einer Liste von Wörterbüchern zu erstellen. Dann berechnen Sie die Gesamtkosten:

>>> import fileparse
>>> with open('portfolio.csv') as lines:
...     portdicts = fileparse.parse_csv(lines, select=['name','shares','price'], types=[str,int,float])
...
>>> portfolio = [ stock.Stock(d['name'], d['shares'], d['price']) for d in portdicts]
>>> portfolio
[<stock.Stock object at 0x10c9e2128>, <stock.Stock object at 0x10c9e2048>, <stock.Stock object at 0x10c9e2080>,
 <stock.Stock object at 0x10c9e25f8>, <stock.Stock object at 0x10c9e2630>, <stock.Stock object at 0x10ca6f748>,
 <stock.Stock object at 0x10ca6f7b8>]
>>> sum([s.cost() for s in portfolio])
44671.15
>>>

Übung 4.4: Verwenden Ihrer Klasse

Ändern Sie die read_portfolio()-Funktion im report.py-Programm so, dass sie ein Portfolio in eine Liste von Stock-Instanzen einliest, wie in Übung 4.3 gezeigt. Nachdem Sie das getan haben, reparieren Sie den gesamten Code in report.py und pcost.py, so dass er mit Stock-Instanzen statt mit Wörterbüchern funktioniert.

Hinweis: Sie sollten keine großen Änderungen am Code vornehmen müssen. Sie werden hauptsächlich die Zugriffe auf Wörterbücher wie s['shares'] in s.shares umwandeln.

Sie sollten Ihre Funktionen wie zuvor ausführen können:

>>> import pcost
>>> pcost.portfolio_cost('portfolio.csv')
44671.15
>>> import report
>>> report.portfolio_report('portfolio.csv', 'prices.csv')
      Name     Shares      Price     Change
---------- ---------- ---------- ----------
        AA        100       9.22     -22.98
       IBM         50     106.28      15.18
       CAT        150      35.46     -47.98
      MSFT        200      20.89     -30.34
        GE         95      13.48     -26.89
      MSFT         50      20.89     -44.21
       IBM        100     106.28      35.84
>>>
✨ Lösung prüfen und üben

Zusammenfassung

Herzlichen Glückwunsch! Sie haben das Klassenlabor abgeschlossen. Sie können in LabEx weitere Labs absolvieren, um Ihre Fähigkeiten zu verbessern.