Anotasi jenis pengembalian Python void

118

Dalam python 3.x, adalah umum untuk menggunakan anotasi tipe kembalian dari suatu fungsi, seperti:

def foo() -> str:
    return "bar"

Apa anotasi yang benar untuk tipe "void"?

Saya sedang mempertimbangkan 3 opsi:

  1. def foo() -> None:
    • bukan IMO logis, karena Nonebukan tipe,
  2. def foo() -> type(None):
    • menggunakan sintaks terbaik yang saya tahu untuk memperolehnya NoneType,
  3. def foo():
    • hilangkan informasi tipe pengembalian eksplisit.

Opsi 2. tampaknya paling logis bagi saya, tetapi saya telah melihat beberapa contoh 1.

Tregoreg
sumber
12
FWIW, Python tidak memiliki fungsi dengan voidtipe kembalian. Fungsi apa pun (atau cabang dalam suatu fungsi) tanpa eksplisit returnakan kembali None. Saya berasumsi OP memahami bahwa, komentar ini sebagian besar untuk kepentingan pembaca di masa mendatang ...
PM 2Ring
Nah, pertanyaan ini tidak sepopuler "mengapa fungsi saya mengembalikan None dengan Python?" (Saya membuat pertanyaan ini), jadi mungkin sebagian besar pembaca sudah mengetahui perilaku default. Dilema 1 vs 2 terpecahkan dalam jawaban. Tapi bagaimana dengan 3? Untuk "prosedur" saya sebenarnya lebih suka opsi 3, tanpa kekacauan yang tidak berguna (bagaimanapun juga, fungsi ini tidak mengembalikan apa pun).
Tomasz Gandor
@TomasSetuju. Ketika suatu fungsi atau metode tidak berisi pernyataan pengembalian, maka tidak perlu menentukan jenis pengembaliannya.
Jeyekomon

Jawaban:

128

Ini langsung dari PEP 484 - dokumentasi Type Hints :

Saat digunakan dalam petunjuk tipe, ekspresi Nonedianggap setara dengan type(None).

Dan, seperti yang Anda lihat sebagian besar contoh digunakan Nonesebagai tipe kembalian.

AKS
sumber
22
Untuk memperjelas, pilih opsi 1 di atas.
Adam Nelson
13
@asmaier menurut pertanyaan ini yang mengutip PEP 484 - Jenis Petunjuk NoReturn Jenis digunakan "... untuk menganotasi fungsi yang tidak pernah kembali secara normal. Misalnya, fungsi yang tanpa syarat menimbulkan pengecualian ..."
Rodrigo Laguna
40

TLDR: Persamaan idiomatik dari voidanotasi tipe kembalian adalah -> None.

def foo() -> None:
    ...

Ini cocok dengan fungsi yang tidak returnatau hanya kosong returnmengevaluasi None.

def void_func():  # unannotated void function
    pass

print(void())  # None

Menghilangkan tipe pengembalian tidak berarti tidak ada nilai pengembalian. Sesuai PEP 484 :

Untuk fungsi yang dicentang, anotasi default untuk argumen dan tipe kembaliannya adalah Any.

Ini berarti nilai dianggap diketik secara dinamis dan mendukung operasi apa pun secara statis . Secara praktis, arti kebalikan dari void.


Mengisyaratkan tipe dengan Python tidak secara ketat membutuhkan tipe sebenarnya. Sebagai contoh, penjelasan dapat menggunakan string dari nama jenis: Union[str, int], Union[str, 'int'], 'Union[str, int]'dan berbagai varian yang setara.

Demikian pula, anotasi jenis Nonedianggap berarti "dari NoneType". Ini dapat digunakan tidak hanya untuk tipe pengembalian, meskipun Anda akan paling sering melihatnya di sana:

bar : None

def foo(baz: None) -> None:
    return None

Ini juga berlaku untuk tipe generik. Misalnya, Anda dapat menggunakan Nonein Generator[int, None, None]untuk menunjukkan generator tidak mengambil atau mengembalikan nilai.


Meskipun PEP 484 menunjukkan bahwa Noneberarti type(None), Anda tidak harus menggunakan bentuk terakhir eksplisit. Spesifikasi petunjuk tipe tidak menyertakan bentuk apa pun type(...). Ini secara teknis adalah ekspresi runtime, dan dukungannya sepenuhnya bergantung pada pemeriksa jenis. The mypyproyek mempertimbangkan untuk membuang dukungan untuk type(None)dan menghapusnya dari 484 juga.

Atau mungkin kita harus memperbarui PEP 484 agar tidak menyarankan yang type(None)valid sebagai sebuah tipe, dan Noneapakah satu-satunya ejaan yang benar? Seharusnya ada satu - dan sebaiknya hanya satu - cara yang jelas untuk melakukannya, dll.

--- JukkaL, 18 Mei 2018

MisterMiyagi
sumber
4
Teriakan besar untuk menjelaskan mengapa opsi ke-3 sebenarnya bukan fungsi kosong sama sekali.
никта