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 .

Reactgular
quelle
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
    [...]
pschill
quelle
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: ...
ein Gast
quelle