Heim > Artikel > Backend-Entwicklung > Eine ausführliche Einführung in Pythons Ententypisierung
Ich glaube, Python-Entwickler sind mit Pythons Duck-Typing vertraut. Die genaue Definition von Duck-Typing in Wikipedia ist „ein Stil des dynamischen Typings“. Bei diesem Stil wird die effektive Semantik eines Objekts nicht durch das Erben von einer bestimmten Klasse oder die Implementierung einer bestimmten Schnittstelle bestimmt, sondern durch den „aktuellen Satz von Methoden und Eigenschaften“. In diesem Artikel erhalten Sie eine Einführung in die Ententypisierung von Python.
Grundlegende Definition des Ententyps
Erstens unterstützt Python keinen Polymorphismus und muss Polymorphismus auch nicht unterstützen. Python ist eine Art Polymorphismus-Sprache, die das Ententypisieren befürwortet.
Das Folgende ist eine Diskussion über Duck Typing aus Wikipedia:
In der Programmierung ist Duck Typing (englisch: duck typing) ein Stil des dynamischen Tippens. Bei diesem Stil wird die effektive Semantik eines Objekts nicht durch das Erben von einer bestimmten Klasse oder die Implementierung einer bestimmten Schnittstelle bestimmt, sondern durch den aktuellen Satz von Methoden und Eigenschaften. Der Name dieses Konzepts stammt von dem von James Whitcomb Riley vorgeschlagenen „Ententest“ kann wie folgt ausgedrückt werden:
„Wenn Sie einen Vogel sehen, der wie eine Ente geht, schwimmt er.“ eine Ente und quakt wie eine Ente. Wenn es wie eine Ente aussieht, dann kann der Vogel eine Ente genannt werden , sondern darauf, wie es verwendet wird. Beispielsweise könnten wir in einer Sprache, die kein Duck-Typing verwendet, eine Funktion schreiben, die ein Objekt vom Typ duck nimmt und dessen Walk- und Bark-Methoden aufruft. In einer Sprache, die Duck-Typing verwendet, kann eine solche Funktion ein Objekt jeden Typs akzeptieren und seine Walk- und Call-Methoden aufrufen. Wenn die aufzurufenden Methoden nicht vorhanden sind, wird ein Laufzeitfehler ausgelöst. Die Tatsache, dass jedes Objekt mit den richtigen Walk- und Call-Methoden von einer Funktion akzeptiert werden kann, führt zu der obigen Aussage, daher der Name dieser Art der Typenbestimmung.
Duck-Typing profitiert oft davon, dass man die Argumenttypen in Methoden und Funktionen nicht testet, sondern sich stattdessen auf Dokumentation, klaren Code und Tests verlässt, um die korrekte Verwendung sicherzustellen. Benutzer, die von statisch zu dynamisch typisierten Sprachen wechseln, versuchen häufig, eine statische Typprüfung (vor der Laufzeit) hinzuzufügen, wodurch die Vorteile und die Skalierbarkeit des Duck-Typings beeinträchtigt und die dynamische Natur der Sprache eingeschränkt werden.
Der folgende Code ist ein einfacher Ententyp
class duck(): def walk(self): print('I walk like a duck') def swim(self): print('i swim like a duck') class person(): def walk(self): print('this one walk like a duck') def swim(self): print('this man swim like a duck')Bei einem Duck-Typ ist uns nicht der Typ des Objekts selbst oder die Klassenvererbung wichtig, sondern wie die Klasse verwendet wird. Wir können die Methoden dieser Klassen über den folgenden Code aufrufen.
def watch_duck(animal): animal.walk() animal.swim() small_duck = duck() watch_duck(small_duck) output >> I walk like a duck i swim like a duck duck_like_man = person() watch_duck(duck_like_man) output >> this one walk like a duck this man swim like a duck class Lame_Foot_Duck(): def swim(self): print('i am lame but i can swim') lame_duck = Lame_Foot_Duck() watch_duck(lame_duck) output >> AttributeError: Lame_Foot_Duck instance has no attribute 'walk'
Die Funktion empfängt das Objekt dieser Klasse und überprüft dann nicht den Typ des Objekts, sondern ruft direkt das Gehen und auf Schwimmfunktionen dieser Objektmethode. Wenn die erforderliche Methode nicht vorhanden ist, wird ein Fehler gemeldet.
Die spezifische Ausführungsform der Ententypisierung in Python ist wie im folgenden Code dargestellt watch_duck
class CollectionClass(): lists = [1,2,3,4] def __getitem__(self, index): return self.lists[index] iter_able_object = CollectionClass() class Another_iterAbleClass(): lists=[1,2,3,4] list_position = -1 def __iter__(self): return self def next(self): #还有更简单的实现,使用生成器或迭代器什么的:) self.list_position += 1 if self.list_position >3: raise StopIteration return self.lists[self.list_position] another_iterable_object=Another_iterAbleClass() print(iter_able_object[1]) print(iter_able_object[1:3]) output>> 2 [2, 3] another_iterable_object[2] output>> Traceback (most recent call last): File "/Users/steinliber/a.py", line 32, in <module> another_iterable_object[2] TypeError: 'Another_iterAbleClass' object does not support indexing print(next(another_iterable_object)) output>> 1 print(next(another_iterable_object)) output>> 2 print(next(iter_able_object)) output>> Traceback (most recent call last): File "/Users/steinliber/a.py", line 29, in <module> print(next(iter_able_object)) TypeError: IterAbleClass object is not an iteratorIn Python ist die Implementierungsmethode von Der obige Code wird als Protokoll bezeichnet. Diese Protokolle können als Benachrichtigungsschnittstellen betrachtet werden, die angeben, welche Methoden des Objekts der Aufrufer aufrufen muss, um diese Funktion zu verwenden, und welche Methoden der Angerufene implementieren muss, um diese Funktion abzuschließen. Der Unterschied zur Schnittstelle in Java besteht darin, dass die Schnittstellenfunktion in Java durch Vererbung implementiert werden muss. Die geerbte Klasse muss alle abstrakten Methoden in der Schnittstelle implementieren, daher wird in Java das Konzept des Typs betont, während
In Python sind die meisten davon informativ. Eine Funktion gibt an, welche Methoden des eingehenden Objekts aufgerufen werden müssen, um eine bestimmte Funktion zu implementieren.
Insbesondere von den beiden oben genannten Klassen implementiert die erste Klasse die Methode protocol
, dann behandelt der Python-Interpreter sie als Sammlung und Sie können Slices für Objekte dieser Klasse verwenden Unterelemente abrufen: Wenn die zweite Klasse die Methoden
implementiert, geht Python davon aus, dass es sich um einen Iterator handelt, und kann jedes Unterelement über eine Schleife für das Objekt dieser Klasse abrufen. Eine Klasse kann Methoden implementieren, die sie implementieren kann, und kann nur in Situationen verwendet werden, in denen dies sinnvoll ist. __getitem__
__iter__
Verglichen mit der oben genannten Duck-Klasse entsprechen das [] zum Kantenschneiden (das tatsächlich die next
-Funktion von Python aufruft) und das zum Schleifen verwendete
-Funktionen. Diese Funktionen empfangen Objekte aller Klassen und Aufrufmethoden in den Objekten, die zur Implementierung der Funktion erforderlich sind, um die Funktion zu implementieren. Wenn das in der Funktion aufgerufene Methodenobjekt nicht vorhanden ist, wird ein Fehler gemeldet. slice
iter()
Wie aus dem oben Gesagten hervorgeht, besteht die Flexibilität der Python-Duck-Typisierung darin, dass sie sich darauf konzentriert, wie das aufgerufene Objekt verwendet wird, und nicht auf den Objekttyp selbst. Daher wird nicht empfohlen, watch_duck
zu verwenden, um den Typ der eingehenden Parameter in Python zu bestimmen. Eine bessere Methode besteht darin, die eingehenden Parameter direkt zu verwenden und try und
Zusammenfassung
Der Inhalt dieses Artikels ist immer noch sehr detailliert Jeder, der Python lernt, kann bei Fragen eine Nachricht hinterlassen.
Ausführlichere Artikel über Pythons Ententypisierung finden Sie auf der chinesischen PHP-Website!