Eine typisierte Welt, die mit Python beginnt

Ab Python 3.5 wurde eine Funktion namens Type Hints eingeführt.

Dies ist eine Spezifikation, mit der Sie Typanmerkungen (Typanmerkungen) hinzufügen können. Sie sieht insbesondere wie folgt aus (Zusammenfassung). Zitiert aus 0484 / # abstract)).

def greeting(name: str) -> str:
    return 'Hello ' + name

Der folgende Teil ist tatsächlich kommentierend.

Typhinweise erwähnen auch Typkommentare in Variablendeklarationen (https://www.python.org/dev/peps/pep-0484/#type-comments).

x = []   # type: List[Employee]

Dies ist wirklich eine Erweiterung des Kommentars, nicht der Syntax, aber wenn Sie diese Typen bereits kommentiert haben, können Sie die obige Notation entführen und in Zukunft können Sie die Typprüfung mit einem Tool durchführen. Es gibt eine Möglichkeit.

Dies ist die typisierte Welt, die in Python eingeführt wurde.

Die hinzugefügte Anmerkung wird zur Laufzeit nicht überprüft. Kurz gesagt, es ist eine Erweiterung des Kommentars. Daher ist es nicht durchsetzbar, führt jedoch zur Laufzeit nichts aus und beeinträchtigt die Leistung nicht.

Daher dient die Syntax im Prinzip der statischen Analyse, die Anmerkungsinformationen jedoch in typing.get_type_hints. Ich denke, es ist möglich, die Laufzeitprüfung selbst zu implementieren (z. B. typeannotations).

Anmerkungsnotation

Ich möchte die Notation von Anmerkungen zusammen mit Typing einführen.

Type aliases

Es ist möglich, Typ-Aliase zu definieren.

Type aliases

Vector = List[float]

Nach meiner persönlichen Erfahrung kann dies jedoch verwirrend sein (es ist schwer zu sagen, ob es sich um eine Klasse oder einen Alias handelt). Sie müssen daher vorsichtig sein, wo Sie es verwenden und wie Sie es benennen.

Callable

Dies ist eine Zusammenfassung der Definitionen von Funktionsargumenten / Rückgabetypen. Es wird verwendet, wenn eine Funktion ein Argument wie eine Rückruffunktion ist oder wenn eine Funktion zurückgegeben wird.

Die Notation lautet "Callable ([Argumenttyp], Rückgabetyp)". Das Folgende ist ein Beispiel für das Annotieren von feeder / async_query, das eine Funktion als Argument mit Callable verwendet.

Callable

from typing import Callable

def feeder(get_next_item: Callable[[], str]) -> None:
    # Body

def async_query(on_success: Callable[[int], None],
                on_error: Callable[[int, Exception], None]) -> None:
    # Body

Generics

Auch sogenannte Generika sind erhältlich. Sie können "List " in Java usw. wie folgt schreiben.

Generics

from typing import Sequence, TypeVar

T = TypeVar('T')      # Declare type variable

def first(l: Sequence[T]) -> T:   # Generic function
    return l[0]

Sie können die gültigen Generika-Typen auch mit "TypeVar" einschränken. Im Folgenden sind nur "str" und "bytes" als AnyStr zulässig.

pep-0484/#generics

from typing import TypeVar

AnyStr = TypeVar('AnyStr', str, bytes)

def concat(x: AnyStr, y: AnyStr) -> AnyStr:
    return x + y

User-defined generic types

Wenn Sie in der sogenannten Generics-Klasse so etwas wie "MyClass " ausführen möchten, definieren Sie es wie folgt.

User-defined generic types

from typing import TypeVar, Generic

T = TypeVar('T')

class LoggedVar(Generic[T]):
    def __init__(self, value: T, name: str, logger: Logger) -> None:
        self.name = name
        self.logger = logger
        self.value = value

    def set(self, new: T) -> None:
        self.log('Set ' + repr(self.value))
        self.value = new

    def get(self) -> T:
        self.log('Get ' + repr(self.value))
        return self.value

    def log(self, message: str) -> None:
        self.logger.info('{}: {}'.format(self.name message))

Jetzt können Sie es so verwenden:

from typing import Iterable

def zero_all_vars(vars: Iterable[LoggedVar[int]]) -> None:
    for var in vars:
        var.set(0)

The Any type

Alle "Typen" sind Untertypen von "Beliebig". Beachten Sie, dass sich "Any" von dem "Objekt" in der Klasse unterscheidet.

Union types

Es ist eine Sammlung von mehreren akzeptablen Typen. "Optional" ist eine Art dieser "Union".

Union types

from typing import Union

def handle_employee(e: Union[Employee, None]) -> None: ...

Dies ist gleichbedeutend mit:

from typing import Optional

def handle_employee(e: Optional[Employee]) -> None: ...

Methode zur Überprüfung

Wie oben erwähnt, deckt die Typanmerkungsnotation meiner Meinung nach die meisten Szenen ab, die Sie eingeben möchten. Es ist jedoch dasselbe wie ein Kommentar, und selbst wenn Sie die von Ihnen hinzugefügte Anmerkung ignorieren, werden Sie es nicht bemerken.

Der Python-Standard bietet kein offizielles Tool zum Überprüfen von Typanmerkungen (ab 3.5). Daher müssen Sie zur Überprüfung ein externes Tool verwenden.

Ein Typ dieses Tools ist "mypy".

mypy

Es wurde von Jukka entwickelt, der auch Autor von typehinting von Python selbst ist, und ich denke, es kann gesagt werden, dass es die De-facto-Standardbibliothek für Typanmerkungen ist.

Für Überprüfungen in der integrierten Entwicklungsumgebung bietet PyCharm Unterstützung. Im Folgenden wird in der Warnung ein numerischer Wert an "Begrüßung" übergeben, der "str" als Argument verwendet.

image

PyCharm unterstützt ursprünglich Anmerkungen in "Dokumentstrings" und Kommentaren und Unterstützung, die in Zukunft den Standard übernommen hat Ich denke, Sie können erwarten, dass das hinzugefügt wird.

Die Python-Entwicklungsumgebung (PTVS) von Visual Studio soll in Ordnung sein, da sie ursprünglich eine starke Typinferenz aufweist, aber es scheint eine Debatte über die Einbeziehung der Notation zu geben.

Use type hints in Python 3.x to infer variable types if possible #82

installiere mypy

Hier werden wir das Einführungsverfahren für die Überprüfung mit mypy vorstellen.

Sie können mypy von pip installieren.

pip install mypy

~~ * Beachten Sie, dass pip install mypy eine völlig andere Bibliothek enthält ~~ Von mypy 0.470 wurde der Bibliotheksname von mypy-lang in mypy geändert

Natürlich basiert es auf Python 3 (es ist in Ordnung, auch wenn es nicht 3.5 ist), aber [es wird in Python 2 unterstützt](http://mypy.readthedocs.org/en/latest/faq.html#all-of-my-code -ist-noch-in-Python-2-was-sind-meine-Optionen). Wenn Sie mypy ab dem 2. November 2015 mit Python 3.5 verwenden möchten, müssen Sie es vom Master installieren. Dies liegt daran, dass die Unterstützung für "Undefined", die in Python 3.5 entfernt wurde, in pypi (Problem 639 noch nicht berücksichtigt wurde. ).

Gehen Sie wie folgt vor, um die Installation vom GitHub-Master durchzuführen:

pip install git+https://github.com/JukkaL/mypy.git@master

Verwendung von Mypy

Es entspricht dem offiziellen Schnellstart, aber Sie können die Prüfung mit dem Befehl mypy ausführen, der nach der Installation verfügbar ist.

mypy PROGRAM

Wenn dies nicht funktioniert, lesen Sie bitte Fehlerbehebung. Die Grundlagen werden hier behandelt.

Wenn Sie es tatsächlich ausführen, lautet das Ausführungsergebnis wie folgt.

>>> mypy examples/basic.py
examples\basic.py:5: error: Argument 1 to "greeting" has incompatible type "int"; expected "str"

Sie können das Modul auch mit der Option -m angeben.

>>> mypy -m examples
examples\__init__.py:1: note: In module imported here:
examples\basic.py:5: error: Argument 1 to "greeting" has incompatible type "int"; expected "str"

Hier ist examples / __ init __. Py wie folgt.

import examples.basic

Da die Prüfung "In hier importiertes Modul:" lautet, scheint beim Targeting von Paketen alles, was nicht aus "__init __. Py" folgt, nicht geprüft zu werden. Seien Sie also vorsichtig, wenn Sie alle Dateien in einem Modul überprüfen möchten.

Bei vorhandenen Bibliotheken ist es nicht möglich, den Quellcode des Inhalts mit Anmerkungen zu versehen und zu umgehen. Daher ist es auch möglich, die Typdefinition nach außen auszuschneiden und zu definieren. Eine Datei, die nur diese Typdefinition beschreibt, wird als Stub-Datei bezeichnet. Ihre Erweiterung lautet "pyi" (TypeScript "d.ts" -Bild).

Wenn Sie die von mypy erstellte pyi-Datei lesen möchten, setzen Sie MYPYPATH.

export MYPYPATH=~/work/myproject/stubs

Wenn Sie die Option "--use-python-path" verwenden, wird auf die Optionen in PYTHONPATH verwiesen.

Derzeit gibt es in TypeScript kein Tool zur Verwaltung von Typdefinitionen wie tsd, sondern [python / typeshed](https: // github. Es scheint, dass die Aggregation zu com / python / typeshed erfolgt (obwohl es noch nicht viele gibt).

Weitere Informationen finden Sie im offiziellen Dokument.

Einführungspolitik

Die folgenden Punkte können als Auswirkungen der Einführung von TypeHints erwartet werden.

Und ich denke, dass die anwendbaren Ziele ungefähr wie folgt sind.

Die folgenden Muster können zum Einfügen von Anmerkungen für ein definiertes Ziel berücksichtigt werden.

Ich denke, bei der Einführung muss zunächst geklärt werden, welche Vorteile Sie erwarten. Wenn dies nicht klar ist, sind die Kriterien für die Anwendung und Implementierung nicht eindeutig.

Dieser Bereich wird derzeit getestet, einschließlich der Frage, ob der erwartete Effekt überhaupt erzielt werden kann. Daher möchte ich ihn hinzufügen, wenn ich Know-how gesammelt habe.

Referenzmaterial

Recommended Posts

Eine typisierte Welt, die mit Python beginnt
[Python] Ein Programm, das Treppen mit # erstellt
Machen Sie eine Lotterie mit Python
Ein Server, der POST-Daten mit flask / python wiedergibt
Ein Memo, dass ich den Datenspeicher mit Python berührt habe
Erstellen Sie ein Verzeichnis mit Python
Python beginnend mit Hallo Welt!
Ein Memo, das mit Python & Spark Daten aus dashDB liest
Verwenden Sie ein Makro, das beim Speichern von Python mit vscode ausgeführt wird
Löse ABC163 A ~ C mit Python
Bedienen Sie den Belegdrucker mit Python
Python-Grafikhandbuch mit Matplotlib.
Lassen Sie uns eine GUI mit Python erstellen.
Löse ABC166 A ~ D mit Python
Erstellen Sie eine virtuelle Umgebung mit Python!
Ich habe mit Python eine Lotterie gemacht.
Erstellen einer virtuellen Umgebung mit Python 3
Löse ABC168 A ~ C mit Python
[Hinweis] Hallo Weltausgabe mit Python
[Python] Generiere ein Passwort mit Slackbot
Löse ABC162 A ~ C mit Python
Löse ABC167 A ~ C mit Python
Löse ABC158 A ~ C mit Python
Lassen Sie uns ein Diagramm mit Python erstellen! !!
[Python] Erbt eine Klasse mit Klassenvariablen
Ich habe mit Python einen Daemon erstellt
Schreiben Sie ein Batch-Skript mit Python3.5 ~
[Python] Erstellen Sie ein Diagramm, das mit Plotly verschoben werden kann
Ich habe ein Paket erstellt, das morphologische Analysegeräte mit Python vergleichen kann
Ich möchte einen Platzhalter verwenden, den ich mit Python entfernen möchte
[Python] Ein Memo, das ich versucht habe, mit Asyncio zu beginnen
Ich habe ein Shuffle gemacht, das mit Python zurückgesetzt (zurückgesetzt) werden kann
Die Geschichte, ein Modul zu erstellen, das E-Mails mit Python überspringt
[Pyenv] Erstellen einer Python-Umgebung mit Ubuntu 16.04
Spiralbuch in Python! Python mit einem Spiralbuch! (Kapitel 14 ~)
Erstellen Sie mit Class einen Python-Funktionsdekorator
Erstellen einer einfachen Power-Datei mit Python
Lassen Sie uns mit Python ein Shiritori-Spiel machen
Installieren Sie Python als Framework mit pyenv
Ich habe mit Python einen Zeichenzähler erstellt
[Python] Zeichnen eines Wirbelmusters mit einer Schildkröte
Ich habe eine Heatmap mit Seaborn [Python] gezeichnet.
[Python] Erstellen Sie mit Anaconda eine virtuelle Umgebung
Erstellen wir mit Python eine kostenlose Gruppe
Ein Memo mit Python2.7 und Python3 in CentOS
Erstellen einer Python 3.6-Umgebung mit Windows + PowerShell
Kartenmietinformationen auf einer Karte mit Python
Durchsuche das Labyrinth mit dem Python A * -Algorithmus
Lassen Sie uns mit Python langsam sprechen
Erstellt eine Reise von Darts mit Python (Nachrichten)
[Python] Eine schnelle Webanwendung mit Bottle!
[AtCoder] Löse ABC1 ~ 100 Ein Problem mit Python
Schreiben Sie einen TCP-Client mit Python Twisted
Was ich mit Python-Arrays gemacht habe
Löse AtCoder ABC168 mit Python (A ~ D)
Erstellen Sie mit Python 3.4 einen Worthäufigkeitszähler
Versuchen Sie HTML-Scraping mit der Python-Bibliothek
Visualisieren Sie Punkt P, der mit Python funktioniert