Анотація типу повернення порожнечі Python


108

У python 3.x зазвичай використовується анотація типу return функції, наприклад:

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

Яка правильна анотація для типу "void"?

Я розглядаю 3 варіанти:

  1. def foo() -> None:
    • не логічне IMO, оскільки Noneне є типом,
  2. def foo() -> type(None):
    • використовуючи найкращий синтаксис, який я знаю, для отримання NoneType,
  3. def foo():
    • опустити явну інформацію про тип повернення.

Варіант 2. мені здається найбільш логічним, але я вже бачив деякі випадки 1.


11
FWIW, Python не має функцій із voidтипом повернення. Будь-яка функція (або гілка у функції) без явного returnповернення повернеться None. Я припускаю, що OP розуміє, що цей коментар здебільшого корисний майбутнім читачам ...
PM 2Ring

Ну, це питання не настільки популярне, як "чому моя функція повертає None в Python?" (Я вигадав це питання), тому, мабуть, більшість читачів вже знають поведінку за замовчуванням. Дилема 1 проти 2 вирішена у відповіді. Але як щодо 3? Для "процедур" я насправді віддав би перевагу варіанту 3, без марного безладу (зрештою, ця функція нічого не повертає).
Томаш Гандор,

@TomaszGandor Погоджуюсь. Коли функція або метод не містять оператора повернення, немає потреби вказувати його тип повернення.
Jeyekomon,

Відповіді:


121

Це прямо з PEP 484 - Документація щодо підказок типу :

При використанні у підказці типу вираз Noneвважається еквівалентом type(None).

І, як ви можете бачити, більшість прикладів використовують Noneяк тип повернення.


22
Для уточнення виберіть варіант 1 вище.
Адам Нельсон,


12
@asmaier згідно з цим запитанням, яке посилається на PEP 484 - Тип підказки NoReturn типу використовується "... для анотації функцій, які ніколи не повертаються нормально. Наприклад, функція, яка безумовно викликає виняток ..."
Родріго Лагуна

37

TLDR: Ідіоматичним еквівалентом voidанотації типу повернення є -> None.

def foo() -> None:
    ...

Це відповідає тому, що функція без returnабо просто оголена returnоцінює None.

def void_func():  # unannotated void function
    pass

print(void())  # None

Якщо пропустити тип повернення, це не означає, що значення повернення не існує. Відповідно до PEP 484 :

Для перевіреної функції анотацією за замовчуванням для аргументів і для типу повернення є Any.

Це означає, що значення вважається динамічним набором і статично підтримує будь-яку операцію . Це практично протилежне значення void.


Натяк на типи в Python не вимагає суто реальних типів. Наприклад, анотації можуть використовувати рядки імен типу: Union[str, int], Union[str, 'int'],'Union[str, int]' а також різні варіанти еквівалентні.

Подібним чином, анотація типу Noneвважається такою, що означаєNoneType". Це можна використовувати не лише для типів повернення, хоча найчастіше ви побачите його там:

bar : None

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

Це також стосується загальних типів. Наприклад, ви можете використовувати Nonein, Generator[int, None, None]щоб вказати, що генератор не приймає або повертає значення.


Незважаючи на те, PEP 484 передбачає , що Noneкошти type(None), ви не повинні використовувати останню форму в явному вигляді. Специфікація натяку на тип не включає жодної форми type(...). Це технічно вираз виконання, і його підтримка повністю залежить від перевірки типу. mypyПроект розглядає можливість видалити підтримку для type(None)і видалити його з 484 , а також.

Або, можливо, нам слід оновити PEP 484, щоб не пропонувати, що type(None)є дійсним як тип, іNone є єдино правильним написанням? Це повинен бути один - і бажано лише один - очевидний спосіб зробити це тощо.

--- JukkaL, 18 травня 2018 р


4
Величезний крик для пояснення, чому 3-й варіант насправді взагалі не є функцією void.
никта
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.