Un'istruzione "with" supporta il tipo di suggerimento?


16

Puoi definire il suggerimento tipo per una variabile definita con la withsintassi?

with example() as x:
    print(x)

Vorrei digitare un suggerimento sopra per dire che xè un str(come esempio).

L'unico modo per aggirare che ho trovato è usare una variabile intermedia, ma questo sembra confuso.

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

Non riesco a trovare un esempio nella documentazione di battitura .


6
Gli ispettori del tipo non dovrebbero essere in grado di dedurre il tipo di xcome tipo di ritorno di example().__enter__()?
pschill

2
Perché vuoi annotare xquando è semplicemente il tipo di ritorno di example.__enter__? Idealmente hai annotato quel metodo / funzione.
a_guest

1
xnon è il valore restituito di example; è il valore di ritorno di example().__enter__().
Chepner,

La maggior parte dei metodi che ho trovato non definisce un suggerimento di tipo per il valore restituito.
Reactgular

1
@Reactgular Quindi la soluzione è creare un file stub per quella funzione, in modo che il controllo del tipo possa inferire il tipo. Di solito annoti ai limiti dell'API, non all'interno. In questo caso è chiaro il tipo viene example. Annotare example.__enter__significa un'annotazione mentre con il tuo approccio dovresti annotare in tutti i luoghi in cui viene utilizzato quel gestore di contesto, in generale in che modo un utente dovrebbe sapere quale sia il tipo di ritorno di un'API se non viene fornita?
a_guest

Risposte:


11

PEP 526, che è stato implementato in Python 3.6, consente di annotare le variabili. Puoi usare, ad esempio,

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

o

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

Questo funziona anche per altri blocchi di codice come for. Ottima risposta, grazie.
Reactgular

Se il gestore del contesto non suggerisce cosa __enter__restituirà il metodo, la digitazione xnon ha alcuno scopo. mypyconsentirà felicemente di associare un valore di qualsiasi tipo x.
Chepner,

@chepner Sì, hai ragione. PyCharm riconosce xcome strin entrambi i casi, ma mypynon lo fa.
pschill

14

Solitamente le annotazioni dei tipi vengono posizionate ai limiti dell'API. In questo caso il tipo dovrebbe essere dedotto da example.__enter__. Nel caso in cui tale funzione non dichiari alcun tipo, la soluzione è quella di creare un file stub corrispondente per aiutare il verificatore del tipo a inferire quel tipo.

Nello specifico ciò significa creare un .pyifile con lo stesso gambo del modulo da cui è Examplestato importato. Quindi è possibile aggiungere il seguente codice:

class Example:
    def __enter__(self) -> str: ...
    def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ...
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.