Objektorientiertes Python
Python ist seit seinem Entwurf eine objektorientierte Sprache. Aus diesem Grund ist es sehr einfach, Klassen und Objekte in Python zu erstellen. In diesem Kapitel stellen wir Pythons objektorientierte Programmierung ausführlich vor.
Wenn Sie zuvor noch nicht mit objektorientierten Programmiersprachen in Berührung gekommen sind, sollten Sie zunächst einige grundlegende Merkmale objektorientierter Sprachen kennenlernen und in Ihrem Kopf ein grundlegendes Konzept der Objektorientierung entwickeln; dies wird Ihnen helfen, Pythons objektorientierte Programmierung leichter zu erlernen.
Betrachten wir als Nächstes kurz einige grundlegende Merkmale der Objektorientierung.
Einführung in die objektorientierte Technologie
- Klasse:Wird verwendet, um eine Sammlung von Objekten mit denselben Attributen und Methoden zu beschreiben. Sie definiert die Attribute und Methoden, die jedem Objekt in der Sammlung gemeinsam sind. Objekte sind Instanzen von Klassen.
- Klassenvariable:Klassenvariablen werden von allen instanziierten Objekten gemeinsam genutzt. Klassenvariablen werden innerhalb der Klasse und außerhalb eines beliebigen Funktionsrumpfs definiert. Klassenvariablen werden normalerweise nicht als Instanzvariablen verwendet.
- Datenmitglieder:Klassenvariablen oder Instanzvariablen, die verwendet werden, um Daten im Zusammenhang mit der Klasse und ihren Instanzobjekten zu verarbeiten.
- Methodenüberschreibung:Wenn eine von der Elternklasse geerbte Methode die Anforderungen der Kindklasse nicht erfüllen kann, kann sie überschrieben werden. Dieser Vorgang wird als Methodenüberschreibung bezeichnet.
- Lokale Variablen:In Methoden definierte Variablen, die sich nur auf die Klasse der aktuellen Instanz auswirken.
- Instanzvariablen:In der Klassendeklaration werden Attribute durch Variablen dargestellt. Solche Variablen werden Instanzvariablen genannt; sie werden innerhalb der Klassendeklaration, aber außerhalb der anderen Membermethoden der Klasse deklariert.
- Vererbung:Das heißt, eine abgeleitete Klasse erbt die Felder und Methoden einer Basisklasse. Vererbung ermöglicht es außerdem, ein Objekt einer abgeleiteten Klasse als Objekt einer Basisklasse zu behandeln. Zum Beispiel gibt es ein Design: Ein Objekt vom Typ Dog leitet sich von der Klasse Animal ab, was eine "ist-ein"-Beziehung simuliert (z. B. Dog ist ein Animal).
- Instanziierung:Erstellen einer Instanz einer Klasse, des konkreten Objekts der Klasse.
- Methode:Eine in einer Klasse definierte Funktion.
- Objekt:Eine Instanz einer Datenstruktur, die durch eine Klasse definiert wird. Objekte enthalten zwei Datenelemente (Klassenvariablen und Instanzvariablen) und Methoden.
Klassen erstellen
Verwenden Sie die class-Anweisung, um eine neue Klasse zu erstellen. Nach class folgt der Klassenname und endet mit einem Doppelpunkt:
class ClassName: '类的帮助信息' #类文档字符串 class_suite #类体
Die Hilfeinformationen der Klasse können über ClassName.__doc__ angezeigt werden.
class_suite besteht aus Klassenmitgliedern, Methoden und Datenattributen.
Beispiel
Das folgende ist ein einfaches Beispiel einer Python-Klasse:
Beispiel
Die Variable empCount ist eine Klassenvariable, deren Wert von allen Instanzen dieser Klasse gemeinsam genutzt wird. Sie können über Employee.empCount innerhalb der Klasse oder außerhalb der Klasse darauf zugreifen.
Die erste Methode, __init__(), ist eine spezielle Methode, die Klassenkonstruktor oder Initialisierungsmethode genannt wird. Diese Methode wird aufgerufen, wenn eine Instanz der Klasse erstellt wird.
self repräsentiert eine Instanz der Klasse. self ist erforderlich, wenn Klassenmethoden definiert werden, obwohl der entsprechende Parameter beim Aufruf nicht übergeben werden muss.
self repräsentiert eine Instanz der Klasse, nicht die Klasse
Klassenmethoden unterscheiden sich nur in einem besonderen Punkt von gewöhnlichen Funktionen – sie müssen einen zusätzlichenersten Parameter haben, dessen Name konventionell self ist.
Das Ausführungsergebnis des obigen Beispiels ist:
<__main__.Test instance at 0x10d066878> __main__.Test
Aus dem Ausführungsergebnis ist sehr deutlich, dass self die Instanz der Klasse repräsentiert, die Adresse des aktuellen Objekts darstellt, währendself.__class__auf die Klasse verweist.
self ist kein Python-Schlüsselwort. Wir können es durch example ersetzen, und es wird trotzdem normal ausgeführt:
Beispiel
Das Ausführungsergebnis des obigen Beispiels ist:
<__main__.Test instance at 0x10d066878> __main__.Test
Instanzobjekte erstellen
Beim Instanziieren einer Klasse verwenden andere Programmiersprachen im Allgemeinen das Schlüsselwort new, aber in Python gibt es dieses Schlüsselwort nicht. Die Klasseninstanziierung ähnelt einem Funktionsaufruf.
Im Folgenden wird der Klassenname Employee zur Instanziierung verwendet und Parameter werden über die __init__-Methode empfangen.
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
Zugriff auf Attribute
Sie können den Punkt.verwenden, um auf die Attribute des Objekts zuzugreifen. Verwenden Sie den Klassennamen wie folgt, um auf Klassenvariablen zuzugreifen:
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Vollständiges Beispiel:
Beispiel
Die Ausgabe der Ausführung des obigen Codes lautet wie folgt:
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
Sie können Klassenattribute wie unten gezeigt hinzufügen, löschen und ändern:
emp1.age = 7 # 添加一个 'age' 属性 emp1.age = 8 # 修改 'age' 属性 del emp1.age # 删除 'age' 属性
Sie können auch die folgenden Funktionen verwenden, um auf Attribute zuzugreifen:
- getattr(obj, name[, default]) : Greift auf das Attribut des Objekts zu.
- hasattr(obj,name) : Prüft, ob ein Attribut vorhanden ist.
- setattr(obj,name,value) : Setzt ein Attribut. Wenn das Attribut nicht existiert, wird ein neues Attribut erstellt.
- delattr(obj, name) : Löscht das Attribut.
Integrierte Klassenattribute von Python
- __dict__ : Die Attribute der Klasse (enthält ein Dictionary, das aus den Datenattributen der Klasse besteht)
- __doc__ : Der Docstring der Klasse
- __name__: Klassenname
- __module__: Das Modul, in dem die Klasse definiert ist (der vollständige Name der Klasse ist '__main__.className'; wenn die Klasse in einem importierten Modul mymod liegt, dann entspricht className.__module__ dem mymod)
- __bases__ : Die Elemente, die alle Elternklassen der Klasse bilden (enthält ein Tupel, das aus allen Elternklassen besteht)
Das folgende Beispiel zeigt den Aufruf der integrierten Klassenattribute von Python:
Beispiel
Die Ausgabe der Ausführung des obigen Codes lautet wie folgt:
Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
Python-Objektzerstörung (Garbage Collection)
Python verwendet die einfache Technik der Referenzzählung, um Müll zu verfolgen und zurückzugewinnen.
Intern zeichnet Python auf, wie viele Referenzen für alle verwendeten Objekte existieren.Eine interne Verfolgungsvariable, genannt Referenzzähler.
Wenn ein Objekt erstellt wird, wird ein Referenzzählwert erstellt. Wenn dieses Objekt nicht mehr benötigt wird, d. h. wenn der Referenzzählwert des Objekts 0 wird, wird es durch Garbage Collection gesammelt. Die Sammlung erfolgt jedoch nicht "sofort"; der Interpreter gibt den vom Müllobjekt belegten Speicherplatz zu einem geeigneten Zeitpunkt frei.
a = 40 # 创建对象 <40> b = a # 增加引用, <40> 的计数 c = [b] # 增加引用. <40> 的计数 del a # 减少引用 <40> 的计数 b = 100 # 减少引用 <40> 的计数 c[0] = -1 # 减少引用 <40> 的计数
Der Garbage-Collection-Mechanismus zielt nicht nur auf Objekte mit einem Referenzzählwert von 0 ab, sondern kann auch zirkuläre Referenzen verarbeiten. Zirkuläre Referenzen beziehen sich auf zwei Objekte, die sich gegenseitig referenzieren, aber auf die keine anderen Variablen verweisen. In diesem Fall ist es nicht ausreichend, sich nur auf die Referenzzählung zu verlassen. Pythons Garbage Collector ist tatsächlich ein Referenzzähler und ein zirkulärer Garbage Collector. Als Ergänzung zur Referenzzählung behält der Garbage Collector auch Objekte mit einer großen Gesamtzuweisung im Auge (d. h. solche, die nicht durch Referenzzählung zerstört werden). In solchen Fällen hält der Interpreter an und versucht, alle nicht referenzierten Zyklen zu bereinigen.
Beispiel
Der Destruktor __del__ wird aufgerufen, wenn das Objekt zerstört wird. Wenn das Objekt nicht mehr verwendet wird, läuft die __del__-Methode:
Beispiel
Das Ausführungsergebnis des obigen Beispiels ist wie folgt:
3083401324 3083401324 3083401324 Point 销毁
Hinweis:Normalerweise müssen Sie eine Klasse in einer separaten Datei definieren,
Klassenvererbung
Einer der Hauptvorteile der objektorientierten Programmierung ist die Wiederverwendung von Code, und eine Möglichkeit, diese Wiederverwendung zu erreichen, ist der Vererbungsmechanismus.
Die durch Vererbung erzeugte neue Klasse wird alsUnterklasseoderabgeleitete Klassebezeichnet, und die Klasse, von der geerbt wird, wird alsBasisklasse、ElternklasseoderSuperklasse。
Vererbungssyntax
class 派生类名(基类名)
...
Einige Merkmale der Vererbung in Python:
- 1. Wenn der Konstruktor der Elternklasse in der Unterklasse benötigt wird, müssen Sie den Konstruktor der Elternklasse explizit aufrufen oder den Konstruktor der Elternklasse nicht überschreiben. Details siehe:Erklärung zur Python-Unterklasse, die den Konstruktor der Elternklasse erbt。
- 2. Beim Aufruf einer Methode der Basisklasse müssen Sie ihr den Namen der Basisklasse voranstellen und die Parametervariable self angeben. Der Unterschied besteht darin, dass Sie beim Aufruf gewöhnlicher Funktionen innerhalb einer Klasse die Parametervariable self nicht angeben müssen.
- 3. Python sucht immer zuerst nach der entsprechenden Art von Methode. Wenn die entsprechende Methode in der abgeleiteten Klasse nicht gefunden werden kann, sucht es anschließend eine nach der anderen in den Basisklassen. (Es sucht zuerst nach der aufgerufenen Methode in der aktuellen Klasse und geht nur dann zur Basisklasse, wenn sie nicht gefunden wird.)
Wenn mehr als eine Klasse im Vererbungs-Tupel aufgeführt ist, wird dies als "Mehrfachvererbung" bezeichnet.
Syntax:
Die Deklaration einer abgeleiteten Klasse ähnelt der ihrer Elternklasse. Die Liste der geerbten Basisklassen folgt auf den Klassennamen, wie unten gezeigt:
class SubClassName (ParentClass1[, ParentClass2, ...]):
...
Beispiel
Die Ausgabe des obigen Codes lautet:
调用子类构造方法 调用子类方法 调用父类方法 父类属性 : 200
Sie können von mehreren Klassen erben
class A: # 定义类 A ..... class B: # 定义类 B ..... class C(A, B): # 继承类 A 和 B .....
Sie können die Methoden issubclass() oder isinstance() verwenden, um dies zu überprüfen.
- issubclass() - Eine boolesche Funktion, die bestimmt, ob eine Klasse eine Unterklasse oder ein Nachkomme einer anderen Klasse ist. Syntax: issubclass(sub, sup)
- isinstance(obj, Class) Eine boolesche Funktion, die true zurückgibt, wenn obj ein Instanzobjekt der Klasse Class oder ein Instanzobjekt einer Unterklasse von Class ist.
Methodenüberschreibung
Wenn die Funktionalität der Methode Ihrer Elternklasse Ihren Anforderungen nicht entspricht, können Sie die Methode der Elternklasse in der Unterklasse überschreiben:
Beispiel:
Beispiel
Nach Ausführung des obigen Codes lautet die Ausgabe wie folgt:
Calling subclass methods
Grundlegende Überladungsmethoden
Die folgende Tabelle listet einige häufige Funktionen auf, die Sie in Ihren eigenen Klassen überschreiben können:
| Nein. | Methode, Beschreibung & Einfacher Aufruf |
|---|---|
| 1 | __init__ ( self [,args...] ) Konstruktor Einfacher Aufruf der Methode:obj = className(args) |
| 2 | __del__( self ) Destruktor-Methode, löscht ein Objekt Einfacher Aufruf der Methode:del obj |
| 3 | __repr__( self ) In eine für den Interpreter lesbare Form umwandeln Einfacher Aufruf der Methode:repr(obj) |
| 4 | __str__( self ) Wird verwendet, um einen Wert in eine für Menschen lesbare Form umzuwandeln Einfacher Methodenaufruf:str(obj) |
| 5 | __cmp__ ( self, x ) Objektvergleich Einfacher Methodenaufruf:cmp(obj, x) |
Operatorüberladung
Python unterstützt auch Operatorüberladung, wie im folgenden Beispiel gezeigt:
Beispiel
Die Ausgabe des obigen Codes lautet:
Vector(7,8)
Klassenattribute und Methoden
Private Attribute einer Klasse
__private_attrs: Zwei führende Unterstriche deklarieren das Attribut als privat; es kann außerhalb der Klasse nicht verwendet oder direkt darauf zugegriffen werden. Wenn es innerhalb von Methoden in der Klasse verwendet wird,self.__private_attrs。
Methoden einer Klasse
Verwenden Sie innerhalb der Klasse das Schlüsselwortdef, um eine Methode für die Klasse zu definieren. Im Gegensatz zu gewöhnlichen Funktionsdefinitionen muss eine Klassenmethode den Parameter self als ersten Parameter enthalten.
Private Methoden einer Klasse
__private_method: Zwei führende Unterstriche deklarieren die Methode als privat; sie kann außerhalb der Klasse nicht aufgerufen werden. Um sie innerhalb der Klasse aufzurufen,self.__private_methods
Beispiel
Python ändert den Namen so, dass er den Klassennamen enthält:
1
2
2
Traceback (most recent call last):
File "test.py", line 17, in <module>
print counter.__secretCount # 报错,实例不能访问私有变量
AttributeError: JustCounter instance has no attribute '__secretCount'
Python erlaubt es Klasseninstanzen nicht, auf private Daten zuzugreifen, aber Sie könnenobject._className__attrName( object_name._class_name__private_attribute_name) verwenden, um auf das Attribut zuzugreifen. Siehe das folgende Beispiel:
#!/usr/bin/python
# -*- coding: UTF-8 -*-
class Example:
__site = "www.example.com"
example = Example()
print example._Example__site
Führen Sie den obigen Code aus, und das Ergebnis ist wie folgt:
www.example.com
Erklärung von einfachem Unterstrich, doppeltem Unterstrich und doppeltem Unterstrich am Anfang und Ende:
-
__foo__: Definiert spezielle Methoden, normalerweise systemdefinierte Namen, wie__init__()und so weiter.
-
_foo: Eine Variable, die mit einem einzelnen Unterstrich beginnt, stellt eine geschützte Typvariable dar, das heißt, auf den geschützten Typ kann nur von sich selbst und Unterklassen zugegriffen werden, und sie kann nicht fürfrom module import * verwendet werden.
-
__foo: Doppelte Unterstriche kennzeichnen eine private Typvariable, auf die nur von der Klasse selbst zugegriffen werden kann.