Methoden#
Eine Methode ist eine Funktion, die mit einer bestimmten Klasse verbunden ist.
Ihr habt bereits die spezielle __init__
-Methode kennengelernt, die bei einer
neuen Instanz aufgerufen wird, wenn diese erstellt wird. Im folgenden Beispiel
definiert ihr eine weitere Methode, circumference
, für die Klasse
Square
; diese Methode kann verwendet werden, um den Umfang für eine
beliebige Square
-Instanz zu berechnen und zurückzugeben. Wie die meisten
benutzerdefinierten Methoden wird circumference
mit einer Syntax aufgerufen,
die dem Zugriff auf Instanzvariablen ähnelt:
>>> class Square:
... def __init__(self):
... self.length = 1
... def circumference(self):
... return 4 * self.length
...
>>> s = Square()
>>> s.length = 5
>>> print(s.circumference())
20
Die Syntax für Methodenaufrufe besteht aus einer Instanz, gefolgt von einem Punkt, gefolgt von der Methode, die auf der Instanz aufgerufen werden soll. Wenn eine Methode auf diese Weise aufgerufen wird, handelt es sich um einen gebundenen Methodenaufruf. Eine Methode kann jedoch auch als ungebundene Methode aufgerufen werden, indem über ihre enthaltende Klasse auf sie zugegriffen wird. Diese Praxis ist weniger praktisch und wird fast nie angewandt, da das erste Argument einer Methode, die auf diese Weise aufgerufen wird, eine Instanz der Klasse sein muss, in der die Methode definiert ist, und weniger klar ist:
>>> print(Square.circumference(s))
20
Wie __init__
wird auch die circumference
-Methode als Funktion innerhalb
der Klasse definiert. Das erste Argument jeder Methode ist die Instanz, von der
oder auf der sie aufgerufen wurde, konventionsgemäß self
genannt. In vielen
Sprachen wird die Instanz this
genannt und nie explizit übergeben.
Methoden können mit Argumenten aufgerufen werden, wenn die Methodendefinitionen
diese Argumente akzeptieren. Diese Version von Square
fügt der
__init__
-Methode ein Argument hinzu, so dass ihr Quadrate mit einer
bestimmten Kantenlänge erstellen könnt, ohne die Kantenlänge nach der Erstellung
eines Quadrats festlegen zu müssen:
>>> class Square:
... def __init__(self, length):
... self.length = length
... def circumference(self):
... return 4 * self.length
Warnung
self.length
und length
sind nicht dasselbe!
self.length
ist die Instanzvariable namenslength
length
ist der lokale Funktionsparameter
In der Praxis würdet ihr den lokalen Funktionsparameter wahrscheinlich als
lng
oder l
bezeichnen, um Verwechslungen zu vermeiden.
Mit dieser Definition von Square
könnt ihr Quadrate mit beliebigen
Kantenlängen mit einem Aufruf der Klasse Square
erstellen. Im Folgenden wird
ein Quadrat mit der Kantenlänge 3
erstellt:
s = Square(3)
Alle Standardfunktionen von Python – Standardargumente, zusätzliche Argumente,
Schlüsselwortargumente usw. – können mit Methoden
verwendet werden. Ihr hättet die erste Zeile von __init__
wie folgt
definieren können:
... def __init__(self, length=1):
Dann würde der Aufruf von Square
mit oder ohne zusätzliches Argument
funktionieren; Square()
würde ein Quadrat mit der Kantenlänge 1
und
Square(3)
ein Quadratmit der Kantenlänge 3
zurückgeben.
Bei einem Methodenaufruf instance.method(arg1, arg2, …)
wandelt Python
diesen in einen normalen Funktionsaufruf um, indem es die folgenden Regeln
anwendet:
Suche nach dem Methodennamen im Instanz-Namensraum. Wenn eine Methode für diese Instanz geändert oder hinzugefügt wurde, wird sie bevorzugt gegenüber Methoden in der Klasse aufgerufen.
Wenn die Methode nicht im Namensraum der Instanz gefunden wird, wird die Methode in der Klasse gesucht. In den vorangegangenen Beispielen ist
class
derSquare
-Typ der Instanzs
.Wenn die Methode immer noch nicht gefunden wurde, wird sie in einer Superklasse gesucht, s.a. Vererbung.
Wenn die Methode gefunden wurde, wird sie als normale Python-Funktion aufgerufen, wobei die Instanz als erstes Argument der Funktion verwendet und alle anderen Argumente im Methodenaufruf um ein Leerzeichen nach rechts verschoben werden. So wird
instance.method(arg1, arg2, …)
zuclass.method(instance, arg1, arg2, …)
.
Statische Methoden#
Genau wie in Java könnt ihr statische Methoden aufrufen, auch wenn keine Instanz
dieser Klasse erstellt wurde. Um eine statische Methode zu erstellen, verwendet den @staticmethod
-Dekorator:
1"""circle module: contains the 'Circle' class"""
2
3
4class Circle:
5 """Circle class.
6
7 The class variable 'circles' contains a list of all circle instances.
8
9 """
10
11 circles = []
12 pi = 3.14159
13
14 def __init__(self, diameter=1):
15 """Create a Circle instance with a given diameter and add an initialised
16 circle to the circles list."""
17 self.diameter = diameter
18 self.__class__.circles.append(self)
19
20 def circumference(self):
21 return self.diameter * self.__class__.pi
22
23 @staticmethod
24 def circumferences():
25 """Static method to sum all circle circumferences."""
26 csum = 0
27 for c in Circle.circles:
28 csum = csum + c.circumference()
29 return csum
- Zeile 11
definiert die Klassenvariable
circles
als zunächst leere Liste allerCircle
-Instanzen.- Zeile 14
fügt initialisierte
Circle
-Instanzen dercircles
-Liste hinzu.
>>> import circle
>>> c1 = circle.Circle(1)
>>> c2 = circle.Circle(2)
>>> circle.Circle.circumferences()
9.424769999999999
>>> c2.diameter = 3
>>> circle.Circle.circumferences()
12.56636
Klassenmethoden#
Klassenmethoden
ähneln den statischen Methoden insofern,
als sie aufgerufen werden können, bevor ein Objekt der Klasse instanziiert
wurde. Allerdings wird den Klassenmethoden implizit die Klasse, zu der sie
gehören, als erster Parameter übergeben:
23 @classmethod
24 def circumferences(cls):
25 """Class method to sum all circle circumferences."""
26 csum = 0
27 for c in cls.circles:
28 csum = csum + c.circumference()
29 return csum
- Zeile 18
Der
@classmethod
-Dekorator wird vor der Methodedef
verwendet.- Zeile 19
Der Klassenparameter ist traditionell
cls
.- Zeile 22
Ihr könnt
cls
anstelle vonself.__class__
verwenden.Durch die Verwendung einer Klassenmethode anstelle einer statischen Methode müsst ihr den Klassennamen nicht hart in
circumferences
codieren.
>>> import circle_cm
>>> c1 = circle_cm.Circle(1)
>>> c2 = circle_cm.Circle(2)
>>> circle_cm.Circle.circumferences()
9.424769999999999