Apakah tipe dukungan pernyataan “with” mengisyaratkan?

16

Bisakah Anda menentukan jenis petunjuk untuk variabel yang ditentukan dengan withsintaks?

with example() as x:
    print(x)

Saya ingin mengetikkan petunjuk di atas untuk mengatakan bahwa itu xadalah str(sebagai contoh).

Satu-satunya cara yang saya temukan adalah menggunakan variabel perantara, tetapi ini terasa membingungkan.

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

Saya tidak dapat menemukan contoh dalam dokumentasi pengetikan .

Reactgular
sumber
6
Bukankah tipe checker dapat menyimpulkan tipe xsebagai tipe pengembalian example().__enter__()?
pschill
2
Mengapa Anda ingin memberi anotasi xpadahal itu hanya tipe pengembalian example.__enter__? Idealnya Anda telah mencatat metode / fungsi tersebut.
a_guest
1
xbukan nilai pengembalian example; itu adalah nilai balik dari example().__enter__().
chepner
Sebagian besar metode yang saya temukan tidak mendefinisikan petunjuk jenis untuk nilai pengembalian.
Reactgular
1
@Reactgular Maka solusinya adalah membuat file rintisan untuk fungsi itu, sehingga pemeriksa tipe dapat menyimpulkan jenisnya. Biasanya Anda membubuhi keterangan di batas API, bukan di dalam. Dalam hal ini jelas jenisnya berasal example. Anotasi example.__enter__berarti satu anotasi sementara dengan pendekatan Anda, Anda harus membuat anotasi di semua tempat di mana manajer konteks itu digunakan, plus secara umum bagaimana seorang pengguna seharusnya mengetahui apa tipe pengembalian API jika itu tidak disediakan?
a_guest

Jawaban:

11

PEP 526, yang telah diimplementasikan dalam Python 3.6, memungkinkan Anda untuk membubuhi keterangan variabel. Anda dapat menggunakan, misalnya,

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

atau

with example() as x:
    x: str
    [...]
pschill
sumber
Ini juga berfungsi untuk blok kode lain seperti for. Jawaban yang bagus, terima kasih.
Reactgular
Jika manajer konteks tidak memberi petunjuk apa __enter__metode yang akan kembali, mengetik xtidak melayani tujuan apa pun. mypyakan dengan senang hati mengizinkan nilai jenis apa pun terikat x.
chepner
@ chepner Ya Anda benar. PyCharm mengakui xseperti strdalam kedua kasus, tetapi mypytidak.
pschill
14

Biasanya anotasi jenis ditempatkan di batas API. Dalam hal ini tipe harus disimpulkan example.__enter__. Jika fungsi tersebut tidak mendeklarasikan tipe apa pun, solusinya adalah membuat file rintisan yang sesuai untuk membantu pemeriksa tipe menyimpulkan tipe itu.

Khususnya ini berarti membuat .pyifile dengan batang yang sama dengan modul dari mana Examplediimpor. Kemudian kode berikut dapat ditambahkan:

class Example:
    def __enter__(self) -> str: ...
    def __exit__(self, exc_type, exc_value, exc_traceback) -> None: ...
seorang tamu
sumber