Cara menentukan jenis pengembalian "nullable" dengan petunjuk jenis

177

Misalkan saya memiliki fungsi:

def get_some_date(some_argument: int=None) -> %datetime_or_None%:
    if some_argument is not None and some_argument == 1:
        return datetime.utcnow()
    else:
        return None

Bagaimana cara menentukan tipe pengembalian untuk sesuatu yang bisa None?

exfizik
sumber

Jawaban:

279

Anda sedang mencari Optional.

Karena jenis pengembalian Anda dapat datetime(dikembalikan dari datetime.utcnow()) atau NoneAnda harus menggunakan Optional[datetime]:

from typing import Optional

def get_some_date(some_argument: int=None) -> Optional[datetime]:
    # as defined

Dari dokumentasi tentang pengetikan, Optionaladalah singkatan untuk:

Optional[X]setara dengan Union[X, None].

di mana Union[X, Y]berarti nilai tipe Xatau Y.


Jika Anda ingin menjadi eksplisit karena kekhawatiran bahwa orang lain mungkin tersandung Optionaldan tidak menyadari artinya, Anda selalu dapat menggunakan Union:

from typing import Union

def get_some_date(some_argument: int=None) -> Union[datetime, None]:

Tapi saya ragu ini adalah ide yang bagus, Optionaladalah nama indikatif dan tidak menghemat beberapa penekanan tombol.

Seperti yang ditunjukkan dalam komentar oleh @ Michael0x2a Union[T, None]diubah Union[T, type(None)]jadi tidak perlu digunakan di typesini.

Secara visual ini mungkin berbeda tetapi secara programatik, dalam kedua kasus, hasilnya persis sama ; Union[datetime.datetime, NoneType]akan menjadi tipe yang disimpan di get_some_date.__annotations__* :

>>> from typing import get_type_hints
>>> print(get_type_hints(get_some_date))
{'return': typing.Union[datetime.datetime, NoneType],
 'some_argument': typing.Union[int, NoneType]}

* Gunakan typing.get_type_hintsuntuk mengambil __annotations__atribut objek alih-alih mengaksesnya secara langsung.

Dimitris Fasarakis Hilliard
sumber
10
Anda dapat menyederhanakan Union[datetime, type(None)]untuk Union[datetime, None]- menurut PEP 484 , menggunakan Nonedalam penjelasan jenis selalu diperlakukan sebagai setara dengan type(None). ( typingDokumentasi sebenarnya digunakan Nonedalam kebanyakan kasus, tetapi tidak di sini, yang merupakan pengawasan).
Michael0x2a
@ Michael0x2a tidak tahu itu, menarik. Menambahkannya :)
Dimitris Fasarakis Hilliard
4
Saya melanjutkan dan mengirimkan tambalan untuk memperbaiki ini sekarang, jadi semoga dokumen akan lebih konsisten tentang ini dalam waktu dekat!
Michael0x2a
1
The Optional[T]tipe terkenal di komunitas pemrograman fungsional. Pembaca tidak hanya akan tahu artinya Union[T, None], tetapi juga akan mengenali pola penggunaan bahwa fungsi akan mengembalikan Tidak ada ketika tidak ada jawaban yang berarti, ada kesalahan, atau hasilnya tidak ditemukan.
minggu