Python - Objektorientiert
Vorherige SeiteNächste Seite
Python ist seit seiner Existenz eine objektorientierte Sprache. Aus diesem Grund ist das Erstellen und Verwenden von Klassen und Objekten geradezu einfach. Dieses Kapitel hilft Ihnen dabei, ein Experte in der Verwendung der objektorientierten Programmierunterstützung von Python zu werden.
Wenn Sie noch keine Erfahrung mit objektorientierter (OO) Programmierung haben, möchten Sie vielleicht einen Einführungskurs dazu konsultieren oder zumindest eine Art Tutorial, damit Sie die grundlegenden Konzepte verstehen.
Hier ist jedoch eine kleine Einführung in die objektorientierte Programmierung (OOP), um Sie auf Geschwindigkeit zu bringen −
Überblick über die OOP-Terminologie
-
Klasse − Ein benutzerdefinierter Prototyp für ein Objekt, der eine Reihe von Attributen definiert, die ein beliebiges Objekt der Klasse charakterisieren. Die Attribute sind Datenelemente (Klassenvariablen und Instanzvariablen) und Methoden, auf die über die Punktnotation zugegriffen wird.
-
Klassenvariable − Eine Variable, die von allen Instanzen einer Klasse geteilt wird. Klassenvariablen werden innerhalb einer Klasse, aber außerhalb der Methoden der Klasse definiert. Klassenvariablen werden nicht so häufig verwendet wie Instanzvariablen.
-
Datenelement − Eine Klassenvariable oder Instanzvariable, die Daten enthält, die einer Klasse und ihren Objekten zugeordnet sind.
-
Funktionsüberladung − Die Zuordnung von mehr als einem Verhalten zu einer bestimmten Funktion. Die durchgeführte Operation variiert je nach Art der beteiligten Objekte oder Argumente.
-
Instanzvariable − Eine Variable, die innerhalb einer Methode definiert ist und nur zur aktuellen Instanz einer Klasse gehört.
-
Vererbung − Die Übertragung der Eigenschaften einer Klasse auf andere davon abgeleitete Klassen.
-
Instanz − Ein einzelnes Objekt einer bestimmten Klasse. Ein Objekt obj, das beispielsweise zu einer Klasse Circle gehört, ist eine Instanz der Klasse Circle.
-
Instanziierung − Die Erstellung einer Instanz einer Klasse.
-
Methode − Eine spezielle Art von Funktion, die in einer Klassendefinition definiert ist.
-
Objekt − Eine eindeutige Instanz einer Datenstruktur, die durch ihre Klasse definiert ist. Ein Objekt umfasst sowohl Datenelemente (Klassenvariablen und Instanzvariablen) als auch Methoden.
-
Operatorüberladung − Die Zuordnung von mehr als einer Funktion zu einem bestimmten Operator.
Klassen erstellen
Die Klasse -Anweisung erstellt eine neue Klassendefinition. Der Name der Klasse folgt direkt auf das Schlüsselwort class gefolgt von einem Doppelpunkt wie folgt:−
class ClassName: 'Optional class documentation string' class_suite
-
Die Klasse hat einen Dokumentationsstring, auf den über ClassName.__doc__ zugegriffen werden kann .
-
Die class_suite besteht aus allen Komponentenanweisungen, die Klassenmitglieder, Datenattribute und Funktionen definieren.
Beispiel
Es folgt das Beispiel einer einfachen Python-Klasse −
class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary
-
Die Variable empCount ist eine Klassenvariable, deren Wert von allen Instanzen dieser Klasse gemeinsam genutzt wird. Darauf kann als Employee.empCount zugegriffen werden von innerhalb der Klasse oder außerhalb der Klasse.
-
Die erste Methode __init__() ist eine spezielle Methode, die als Klassenkonstruktor oder Initialisierungsmethode bezeichnet wird und von Python aufgerufen wird, wenn Sie eine neue Instanz dieser Klasse erstellen.
-
Sie deklarieren andere Klassenmethoden wie normale Funktionen mit der Ausnahme, dass das erste Argument jeder Methode self ist . Python fügt das self hinzu Argument zur Liste für Sie; Sie müssen es nicht einschließen, wenn Sie die Methoden aufrufen.
Instanzobjekte erstellen
Um Instanzen einer Klasse zu erstellen, rufst du die Klasse mit dem Klassennamen auf und übergibst ihre Argumente __init__ Methode akzeptiert.
"This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000)
Auf Attribute zugreifen
Sie greifen auf die Attribute des Objekts zu, indem Sie den Punktoperator mit Objekt verwenden. Auf die Klassenvariable würde mit dem Klassennamen wie folgt zugegriffen:−
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Jetzt alle Konzepte zusammenfügen −
Live-Demo#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "This would create first object of Employee class" emp1 = Employee("Zara", 2000) "This would create second object of Employee class" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
Sie können Attribute von Klassen und Objekten jederzeit hinzufügen, entfernen oder ändern −
emp1.age = 7 # Add an 'age' attribute. emp1.age = 8 # Modify 'age' attribute. del emp1.age # Delete 'age' attribute.
Anstatt die normalen Anweisungen zum Zugriff auf Attribute zu verwenden, können Sie die folgenden Funktionen verwenden −
-
Das getattr(obj, name[, default]) − um auf das Attribut des Objekts zuzugreifen.
-
Der hasattr(obj,name) − zu prüfen, ob ein Attribut existiert oder nicht.
-
Der setattr(obj,name,wert) − um ein Attribut zu setzen. Wenn das Attribut nicht existiert, wird es erstellt.
-
Das delattr(obj, name) − um ein Attribut zu löschen.
hasattr(emp1, 'age') # Returns true if 'age' attribute exists getattr(emp1, 'age') # Returns value of 'age' attribute setattr(emp1, 'age', 8) # Set attribute 'age' at 8 delattr(empl, 'age') # Delete attribute 'age'
Integrierte Klassenattribute
Jede Python-Klasse folgt weiterhin den eingebauten Attributen, und auf sie kann wie auf jedes andere Attribut mit dem Punktoperator zugegriffen werden −
-
__dict__ − Wörterbuch, das den Namensraum der Klasse enthält.
-
__doc__ − Klassendokumentationsstring oder keiner, falls nicht definiert.
-
__name__ − Klassenname.
-
__modul__ − Modulname, in dem die Klasse definiert ist. Dieses Attribut ist im interaktiven Modus "__main__".
-
__basen__ − Ein möglicherweise leeres Tupel, das die Basisklassen in der Reihenfolge ihres Auftretens in der Basisklassenliste enthält.
Lassen Sie uns für die obige Klasse versuchen, auf alle diese Attribute zuzugreifen −
Live-Demo#!/usr/bin/python class Employee: 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
Employee.__doc__: Common base class for all employees Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0xb7c84994>, 'empCount': 2, 'displayEmployee': <function displayEmployee at 0xb7c8441c>, '__doc__': 'Common base class for all employees', '__init__': <function __init__ at 0xb7c846bc>}
Zerstören von Objekten (Garbage Collection)
Python löscht nicht benötigte Objekte (eingebaute Typen oder Klasseninstanzen) automatisch, um Speicherplatz freizugeben. Der Prozess, bei dem Python regelmäßig Speicherblöcke zurückfordert, die nicht mehr verwendet werden, wird als Garbage Collection bezeichnet.
Der Garbage Collector von Python wird während der Programmausführung ausgeführt und ausgelöst, wenn die Referenzanzahl eines Objekts Null erreicht. Die Referenzanzahl eines Objekts ändert sich, wenn sich die Anzahl der darauf verweisenden Aliase ändert.
Der Verweiszähler eines Objekts erhöht sich, wenn ihm ein neuer Name zugewiesen oder es in einen Container (Liste, Tupel oder Wörterbuch) platziert wird. Der Referenzzähler des Objekts verringert sich, wenn es mit del gelöscht wird , seine Referenz wird neu zugewiesen oder seine Referenz verlässt den Gültigkeitsbereich. Wenn der Referenzzähler eines Objekts Null erreicht, sammelt Python ihn automatisch.
a = 40 # Create object <40> b = a # Increase ref. count of <40> c = [b] # Increase ref. count of <40> del a # Decrease ref. count of <40> b = 100 # Decrease ref. count of <40> c[0] = -1 # Decrease ref. count of <40>
Sie werden normalerweise nicht bemerken, wenn der Garbage Collector eine verwaiste Instanz zerstört und ihren Speicherplatz zurückfordert. Aber eine Klasse kann die spezielle Methode __del__() implementieren , ein sogenannter Destruktor, der aufgerufen wird, wenn die Instanz zerstört werden soll. Diese Methode kann verwendet werden, um alle Nicht-Speicherressourcen zu bereinigen, die von einer Instanz verwendet werden.
Beispiel
Dieser __del__()-Destruktor gibt den Klassennamen einer Instanz aus, die zerstört werden soll −
Live-Demo#!/usr/bin/python class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "destroyed" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts del pt1 del pt2 del pt3
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
3083401324 3083401324 3083401324 Point destroyed
Hinweis − Idealerweise sollten Sie Ihre Klassen in einer separaten Datei definieren, dann sollten Sie sie mit import in Ihre Hauptprogrammdatei importieren Aussage.
Klassenvererbung
Anstatt ganz von vorne zu beginnen, können Sie eine Klasse erstellen, indem Sie sie von einer bereits vorhandenen Klasse ableiten, indem Sie die Elternklasse in Klammern nach dem neuen Klassennamen auflisten.
Die untergeordnete Klasse erbt die Attribute ihrer übergeordneten Klasse, und Sie können diese Attribute so verwenden, als ob sie in der untergeordneten Klasse definiert wären. Eine untergeordnete Klasse kann auch Datenelemente und Methoden der übergeordneten Klasse überschreiben.
Syntax
Abgeleitete Klassen werden ähnlich wie ihre Elternklasse deklariert; jedoch wird nach dem Klassennamen −
eine Liste von Basisklassen angegeben, von denen geerbt werden sollclass SubClassName (ParentClass1[, ParentClass2, ...]): 'Optional class documentation string' class_suite
Beispiel
Live-Demo#!/usr/bin/python class Parent: # define parent class parentAttr = 100 def __init__(self): print "Calling parent constructor" def parentMethod(self): print 'Calling parent method' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "Parent attribute :", Parent.parentAttr class Child(Parent): # define child class def __init__(self): print "Calling child constructor" def childMethod(self): print 'Calling child method' c = Child() # instance of child c.childMethod() # child calls its method c.parentMethod() # calls parent's method c.setAttr(200) # again call parent's method c.getAttr() # again call parent's method
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
Calling child constructor Calling child method Calling parent method Parent attribute : 200
Auf ähnliche Weise können Sie eine Klasse von mehreren übergeordneten Klassen wie folgt steuern −
class A: # define your class A ..... class B: # define your class B ..... class C(A, B): # subclass of A and B .....
Sie können die Funktionen issubclass() oder isinstance() verwenden, um eine Beziehung zwischen zwei Klassen und Instanzen zu überprüfen.
-
Die issubclass(sub, sup) Die boolesche Funktion gibt wahr zurück, wenn die angegebene Unterklasse sub ist tatsächlich eine Unterklasse der Oberklasse sup .
-
Die isinstance(obj, Class) Die boolesche Funktion gibt wahr zurück, wenn obj ist eine Instanz der Klasse Class oder ist eine Instanz einer Unterklasse von Class
Überschreiben von Methoden
Sie können die Methoden Ihrer übergeordneten Klasse jederzeit überschreiben. Ein Grund für das Überschreiben der übergeordneten Methoden ist, dass Sie möglicherweise spezielle oder andere Funktionen in Ihrer Unterklasse wünschen.
Beispiel
Live-Demo#!/usr/bin/python class Parent: # define parent class def myMethod(self): print 'Calling parent method' class Child(Parent): # define child class def myMethod(self): print 'Calling child method' c = Child() # instance of child c.myMethod() # child calls overridden method
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
Calling child method
Basisüberladungsmethoden
Die folgende Tabelle listet einige allgemeine Funktionen auf, die Sie in Ihren eigenen Klassen überschreiben können −
Sr.No. | Methode, Beschreibung &Musteraufruf |
---|---|
1 | __init__ ( self [,args...] ) Konstruktor (mit optionalen Argumenten) Beispielaufruf:obj =className(args) |
2 | __del__( self ) Destruktor, löscht ein Objekt Beispielaufruf:del obj |
3 | __repr__( self ) Auswertbare Zeichenfolgendarstellung Beispielaufruf:repr(obj) |
4 | __str__( self ) Druckbare Zeichenfolgendarstellung Beispielaufruf:str(obj) |
5 | __cmp__ ( selbst, x ) Objektvergleich Beispielaufruf:cmp(obj, x) |
Operatoren überladen
Angenommen, Sie haben eine Vector-Klasse erstellt, um zweidimensionale Vektoren darzustellen. Was passiert, wenn Sie sie mit dem Plus-Operator hinzufügen? Höchstwahrscheinlich wird Python Sie anschreien.
Sie könnten jedoch __add__ definieren Methode in Ihrer Klasse, um eine Vektoraddition durchzuführen, und dann würde sich der Plusoperator wie erwartet verhalten −
Beispiel
Live-Demo#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
Vector(7,8)
Verbergen von Daten
Die Attribute eines Objekts können außerhalb der Klassendefinition sichtbar sein oder nicht. Sie müssen Attribute mit einem doppelten Unterstrich als Präfix benennen, und diese Attribute sind dann für Außenstehende nicht direkt sichtbar.
Beispiel
Live-Demo#!/usr/bin/python class JustCounter: __secretCount = 0 def count(self): self.__secretCount += 1 print self.__secretCount counter = JustCounter() counter.count() counter.count() print counter.__secretCount
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
1 2 Traceback (most recent call last): File "test.py", line 12, in <module> print counter.__secretCount AttributeError: JustCounter instance has no attribute '__secretCount'
Python schützt diese Mitglieder, indem es den Namen intern so ändert, dass er den Klassennamen enthält. Sie können auf solche Attribute wie object._className__attrName zugreifen . Wenn Sie Ihre letzte Zeile wie folgt ersetzen würden, dann funktioniert es für Sie −
......................... print counter._JustCounter__secretCount
Wenn der obige Code ausgeführt wird, erzeugt er das folgende Ergebnis −
1 2 2
Python