Unterstützt eine "with" -Anweisung Typangaben?


16

Können Sie den Typhinweis für eine mit der withSyntax definierte Variable definieren ?

with example() as x:
    print(x)

Ich möchte den obigen Hinweis eingeben, um zu sagen, dass dies xein str(als Beispiel) ist.

Die einzige Lösung, die ich gefunden habe, ist die Verwendung einer Zwischenvariablen, aber das fühlt sich hackig an.

with example() as x:
    y: str = x
    print(y)

Ich kann kein Beispiel in der Schreibdokumentation finden .


6
Sollten Typprüfer nicht in der Lage sein, den Typ xals Rückgabetyp von abzuleiten example().__enter__()?
11.

2
Warum möchten Sie Anmerkungen machen, xwenn es sich lediglich um den Rückgabetyp handelt example.__enter__? Idealerweise haben Sie diese Methode / Funktion mit Anmerkungen versehen.
a_guest

1
xist nicht der Rückgabewert von example; Es ist der Rückgabewert von example().__enter__().
Chepper

Die meisten Methoden, die ich gefunden habe, definieren keinen Typhinweis für den Rückgabewert.
Reactgular

1
@Reactgular Dann besteht die Lösung darin, eine Stub-Datei für diese Funktion zu erstellen , damit die Typprüfung auf den Typ schließen kann. Normalerweise kommentieren Sie an den API-Grenzen, nicht innerhalb. In diesem Fall ist klar, dass der Typ stammt example. example.__enter__Annotieren bedeutet eine Annotation, während Sie bei Ihrem Ansatz an allen Stellen, an denen dieser Kontextmanager verwendet wird, Annotationen vornehmen müssten. Außerdem , wie soll ein Benutzer im Allgemeinen wissen, was der Rückgabetyp einer API überhaupt ist, wenn er nicht bereitgestellt wird?
a_guest

Antworten:


11

Mit PEP 526, das in Python 3.6 implementiert wurde, können Sie Variablen mit Anmerkungen versehen. Sie können zum Beispiel verwenden

x: str
with example() as x:
    [...]

oder

with example() as x:
    x: str
    [...]

Dies funktioniert auch für andere Codeblöcke wie for. Tolle Antwort, danke.
Reactgular

Wenn der Kontextmanager nicht angibt, was die __enter__Methode zurückgeben wird, hat die Eingabe xkeinen Zweck. mypyermöglicht gerne, dass ein Wert eines beliebigen Typs gebunden wird x.
Chepper

@chepner Ja du hast recht. PyCharm erkennt xwie strin beiden Fällen, aber mypynicht.
11.

14

Normalerweise werden Typanmerkungen an den API-Grenzen platziert. In diesem Fall sollte der Typ abgeleitet werden example.__enter__. Falls diese Funktion keine Typen deklariert, besteht die Lösung darin, eine entsprechende Stub-Datei zu erstellen , damit die Typprüfung auf diesen Typ schließen kann.

Dies bedeutet insbesondere, dass eine .pyiDatei mit demselben Stamm erstellt wird wie das Modul, aus dem Exampleimportiert wurde. Dann kann der folgende Code hinzugefügt werden:

class Example:
    def __enter__(self) -> str: ...
    def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ...
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.