Guten Tag, Freunde. Wir erhöhen weiterhin die Intensität des Starts neuer Kurse und freuen uns, Ihnen mitteilen zu können, dass die Kurse des Kurses 
"Webentwickler in Python" Ende April beginnen werden. In dieser Hinsicht teilen wir traditionell die Übersetzung von nützlichem Material. Fangen wir an.
Python ist als dynamische Schreibsprache bekannt. Es ist sehr einfach, DSL-ähnliche Frameworks zu schreiben, die mit statischen Typprüfungstools nur schwer zu analysieren sind. Trotzdem können 
wir mit den neuesten funktionalen Innovationen von 
mypy wie 
Protokollen und 
Literaltypen sowie der grundlegenden Unterstützung für Metaklassen und Deskriptorunterstützung häufig genaue Typen erhalten, aber es ist immer noch schwierig, falsch positive und andere negative Faktoren zu vermeiden. Um dieses Problem zu lösen und zu vermeiden, dass das Typsystem für jedes Framework 
angepasst werden muss, unterstützt 
mypy ein 
Plug-In- System. Plugins sind Module in Python, die Plugin-Hooks bereitstellen, die 
mypy aufruft , wenn die Arten von Klassen und Funktionen überprüft werden, die mit einer Bibliothek oder einem Framework interagieren. Somit ist es möglich, den Typ der zurückgegebenen Funktion, der ansonsten äußerst schwierig auszudrücken ist, genauer zu unterscheiden oder automatisch einige Klassenmethoden zu generieren, um die Auswirkungen des Dekorateurs widerzuspiegeln. Weitere Informationen zur Architektur des Plug-In-Systems und die vollständige Liste der Funktionen finden Sie in der 
Dokumentation .
 Verwandte Plugins für die StandardbibliothekMypy enthält
Verwandte Plugins für die StandardbibliothekMypy enthält Standard-Plugins zum Implementieren grundlegender Funktionen und Klassen sowie 
dataclasses für 
ctypes , 
dataclasses und 
dataclasses . Es enthält auch Plugins für 
attrs (es war in der Vergangenheit das erste Plugin eines Drittanbieters, das für 
mypy geschrieben wurde ). Mit diesen Plugins kann 
mypy mithilfe dieser Bibliotheksfunktionen Typen genauer bestimmen und den Code korrekt auf Typ überprüfen. Um dies anhand eines Beispiels zu zeigen, sehen Sie sich ein Code-Snippet an:
 from dataclasses import dataclass from typing import Generic, TypeVar @dataclass class TaggedVector(Generic[T]): data: List[T] tag: str position = TaggedVector([0, 0, 0], 'origin') 
Oben wird 
get_class_decorator_hook() aufgerufen, wenn die Klasse definiert wird. Dadurch werden dem Funktionskörper automatisch generierte Methoden 
__init__() , einschließlich 
__init__() . 
Mypy verwendet einen solchen Konstruktor, um 
TaggedVector[int] als 
position korrekt zu berechnen. Wie Sie dem Beispiel entnehmen können, funktionieren Plugins auch mit generischen Klassen.
Hier ist ein weiterer Code:
 from contextlib import contextmanager @contextmanager def timer(title: str) -> Iterator[float]: ... with timer(9000) as tm: ... 
Hier gibt 
get_function_hook() den genauen Rückgabetyp für den 
contextmanager Dekorator an, sodass Aufrufe der dekorierten Funktion auf Übereinstimmung mit einem bestimmten Typ überprüft werden können. Jetzt kann 
mypy den Fehler erkennen: Das Argument für 
timer() sollte eine Zeichenfolge sein.
Eine Kombination aus Plugins und StubsNeben der Verwendung dynamischer Python-Funktionen stoßen Frameworks häufig auf das Problem großer APIs. 
Mypy benötigt 
Stub- Dateien für Bibliotheken, um den Code zu testen, der diese Bibliotheken verwendet (nur wenn die Bibliothek keine integrierten Anmerkungen enthält, was nicht so häufig vorkommt). Das Verteilen von Stubs für große Frameworks mit 
typisierten Daten ist keine gängige Praxis:
- Typeshed hat einen relativ langsamen Release-Zyklus (im Lieferumfang von mypy enthalten ).
- Unvollständige Stubs können zu falschen Anrufen führen, die äußerst schwer zu vermeiden sind.
- Mischen Sie nicht nur Stubs aus verschiedenen typisierten Versionen.
In 
PEP 561 eingeführte Stub-Pakete führen Folgendes aus:
- Entwickler können Stub-Pakete so oft veröffentlichen, wie sie möchten.
- Benutzer, die sich nicht für die Verwendung des Pakets entschieden haben, sehen keine Fehlalarme.
- Sie können beliebige Versionen mehrerer verschiedener Stub-Pakete sicher installieren.
Darüber hinaus können Sie mit 
pip verschiedene Stubs für Bibliotheken und die entsprechenden 
mypy- Plugins in einer Distribution kombinieren. Stubs für das 
mypy- Framework oder das entsprechende Plugin können einfach entwickelt und zu einer Distribution zusammengefasst werden. 
Dies ist äußerst nützlich, da Plugins fehlende oder ungenaue Definitionen in Stubs ausfüllen.
Das neueste Beispiel für ein solches Paket sind 
SQLAlchemy-Stubs und -Plugins mit der ersten öffentlichen Version von Version 0.1, die vor einiger Zeit auf PyPI veröffentlicht wurde. Trotz der Tatsache, dass dieses Projekt in der frühen Alpha-Version vorliegt, können wir es sicher in DropBox verwenden, um die Typprüfung zu verbessern. Das Plugin versteht die grundlegenden ORM-Deklarationen:
 from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) 
Im obigen Code-Snippet verwendet das Plugin 
get_dynamic_class_hook() , um 
mypy mitzuteilen, dass Base eine gültige Basisklasse ist, auch wenn es nicht so aussieht. Anschließend wird 
get_base_class_hook() aufgerufen, um den Benutzer zu definieren, und es werden mehrere automatisch generierte Attribute 
get_base_class_hook() . Als Nächstes erstellen wir eine Instanz des Modells:
user = User(id=42, name=42)get_function_hook() aufgerufen, daher kann 
mypy einen Fehler anzeigen: Anstelle des Benutzernamens wird ein 
integer Wert empfangen.
Stubs definieren 
Column als 
generischen Deskriptor, damit die Modellattribute die richtigen Typen erhalten:
 id_col = User.id  
Wir begrüßen PRs, die Stubs präzisere Typen hinzufügen (der Fortschritt für Kernmodule wird 
hier verfolgt).
Hier sind einige Fallstricke, die wir bei der Arbeit an Steckern entdeckt haben:
- Verwenden Sie __getattr__(), um Fehlalarme in den frühen Phasen zu vermeiden, wenn Stubs nicht abgeschlossen sind (dies verhindert Mypy- Fehler, wenn Modulattribute fehlen). Sie können dies auch in__init__.pyDateien verwenden, wenn Submodule fehlen.
- Deskriptoren helfen häufig bei genaueren Typdefinitionen für den Zugriff auf benutzerdefinierte Attribute (wie im oben beschriebenen Spaltenbeispiel). Die Verwendung von Deskriptoren ist auch dann in Ordnung, wenn für die tatsächliche Implementierung der Laufzeit ein komplexerer Mechanismus verwendet wird, beispielsweise eine Metaklasse.
- Deklarieren Sie die Framework-Klassen ohne zu zögern als verallgemeinert. Trotz der Tatsache, dass sie zur Laufzeit nicht so sind, können Sie mit dieser Technik den Typ einiger Elemente des Frameworks genauer bestimmen, während Laufzeitfehler leicht umgangen werden können. (Wir hoffen, dass Frameworks nach und nach integrierte Unterstützung für generische Typen hinzufügen und die entsprechenden Klassen explizit von typing.Generic.)
Kürzlich veröffentlichte mypy PluginsFür die beliebten Python-Frameworks sind bereits mehrere Plugins verfügbar. Neben dem oben erwähnten 
SQLAlchemy- Plugin enthalten andere bemerkenswerte Beispielpakete mit Stubs und das integrierte 
mypy- Plugin Stubs für die 
Django- und 
Zope- Schnittstellen. An diesen Projekten wird aktiv gearbeitet.
Installieren und Verbinden von Stub- und Plugin-PaketenVerwenden Sie pip, um das Plugin-Paket für 
mypy und / oder stub in einer virtuellen Umgebung zu installieren, in der 
mypy bereits 
installiert ist :
  $ pip install sqlalchemy-stubs 
Mypy erkennt installierte Stubs automatisch. Um installierte Plugins zu verbinden, fügen Sie sie direkt in mypy.ini (oder in die Benutzerkonfigurationsdatei) ein:
 [mypy] plugins = sqlmypy, mypy_django_plugin.main 
Mypy- Plugins entwickeln und Stubs schreiben
Wenn Sie ein Paket von Stubs und Plugins für das von Ihnen verwendete Framework entwickeln möchten, können wir 
das Repository sqlalchemy-stubs als Vorlage verwenden. Es enthält eine 
setup.py , Infrastrukturtests mit datengesteuerten Tests und eine Beispiel-Plug-In-Klasse mit einer Reihe von Hooks für das Plug-In (Plugin-Hooks). Wir empfehlen die Verwendung von 
stubgen , um die mit 
mypy gelieferten Stubs automatisch zu generieren und sie zu verwenden. 
Stubgen hat sich in 
mypy 0.670 Stubgen mypy 0.670 verbessert.
Lesen Sie die 
Dokumentation, wenn Sie mehr über das 
mypy- Plugin- 
System erfahren 
möchten . Sie können auch im Internet nach den Quellcodes der im Artikel beschriebenen Plugins suchen. Wenn Sie Fragen haben, können Sie diese 
hier stellen .
Der 15. April wird ein kostenloses 
offenes Webinar über den Kurs sein, das von einem der Organisatoren der Moskauer Python-Community - 
Vladimir Filonov - abgehalten wird. 
Melden Sie sich an, es wird interessant sein. Und jetzt warten wir auf Ihre Kommentare zum übersetzten Material.