Czy instrukcja „with” obsługuje podpowiedzi typu?

16

Czy potrafisz zdefiniować wskazówkę dotyczącą typu dla zmiennej zdefiniowanej withskładnią?

with example() as x:
    print(x)

Chciałbym wpisać podpowiedź powyżej, aby powiedzieć, że xjest to str(jako przykład).

Jedyne obejście, które znalazłem, to użycie zmiennej pośredniej, ale wydaje się to hacking.

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

Nie mogę znaleźć przykładu w dokumentacji do pisania .

Reactgular
źródło
6
Czy weryfikatory typów nie powinny być w stanie wywnioskować typu xjako typu zwracanego example().__enter__()?
pschill
2
Dlaczego chcesz dodawać adnotacje, xgdy jest to po prostu typ zwracany example.__enter__? Najlepiej, jeśli opisałeś tę metodę / funkcję.
a_guest
1
xnie jest wartością zwracaną example; jest to wartość zwracana z example().__enter__().
chepner
Większość znalezionych metod nie definiuje podpowiedzi typu dla zwracanej wartości.
Reactgular
1
@Reactgular Następnie rozwiązaniem jest utworzenie pliku pośredniczącego dla tej funkcji, aby moduł sprawdzania typu mógł wywnioskować typ. Zazwyczaj adnotacja odbywa się na granicach interfejsu API, a nie wewnątrz. W tym przypadku jasne jest, że typ pochodzi example. Adnotacje example.__enter__oznaczają jedną adnotację, podczas gdy w swoim podejściu musiałbyś adnotować we wszystkich miejscach, w których używany jest ten menedżer kontekstu, a także ogólnie w jaki sposób użytkownik powinien wiedzieć, jaki jest typ zwracanego interfejsu API, jeśli nie jest on dostarczony?
a_guest

Odpowiedzi:

11

PEP 526, który został zaimplementowany w Pythonie 3.6, umożliwia dodawanie adnotacji do zmiennych. Możesz użyć na przykład

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

lub

with example() as x:
    x: str
    [...]
pschill
źródło
Działa to również w przypadku innych bloków kodu, takich jak for. Świetna odpowiedź, dziękuję.
Reactgular
Jeśli menedżer kontekstu nie podpowie, co __enter__zwróci metoda, pisanie xnie będzie miało żadnego celu. mypyz radością zezwoli na związanie dowolnej wartości x.
chepner
@chepner Tak masz rację. PyCharm rozpoznaje xjak strw obu przypadkach, ale mypynie.
pschill
14

Zazwyczaj adnotacje typu są umieszczane na granicach interfejsu API. W takim przypadku typ należy wywnioskować z example.__enter__. W przypadku, gdy ta funkcja nie deklaruje żadnych typów, rozwiązaniem jest utworzenie odpowiedniego pliku pośredniczącego , aby pomóc sprawdzającemu typowi wnioskować o tym typie.

W szczególności oznacza to utworzenie .pyipliku z tym samym rdzeniem, co moduł, z którego Examplezostał zaimportowany. Następnie można dodać następujący kod:

class Example:
    def __enter__(self) -> str: ...
    def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ...
gość
źródło