Як я можу вказати тип функції у підказках щодо мого типу?


137

Я хочу використовувати підказки типу в моєму поточному проекті Python 3.5. Моя функція повинна отримувати функцію як параметр.

Як я можу вказати функцію типу в підказках типу?

import typing

def my_function(name:typing.AnyStr, func: typing.Function) -> None:
    # However, typing.Function does not exist.
    # How can I specify the type function for the parameter `func`?

    # do some processing
    pass

Я перевірив PEP 483 , але там не знайшов підказки щодо типу функції.


21
ФункціяCallable
jonrsharpe

3
python.org/dev/peps/pep-0483/#fundamental-building-blocks , остання точка кулі перед "ми можемо додати".

Відповіді:


174

Як @jonrsharpe зазначив у коментарі, це можна зробити за допомогою typing.Callable:

from typing import AnyStr, Callable

def my_function(name: AnyStr, func: Callable) -> None:

Випуск полягає в тому, що Callableвін самостійно перекладається, Callable[..., Any]що означає:

Викликається приймає будь-яку кількість аргументів / тип та повертає значення будь-якого типу. У більшості випадків це не те, що ви хочете, оскільки ви дозволяєте майже будь-яку функцію передавати. Ви хочете, щоб параметри функцій та типи повернення також натякалися.

Ось чому багато хто typesз typingних перевантажений, щоб підтримувати суб-сценарії, що позначають ці додаткові типи. Так, якщо, наприклад, у вас була функція, sumяка займає два intс і повертає int:

def sum(a: int, b: int) -> int: return a+b

Ваша примітка до цього буде:

Callable[[int, int], int]

тобто параметри суб-сценарії у зовнішній підписці з типом повернення як другий елемент у зовнішній підписці. В загальному:

Callable[[ParamType1, ParamType2, .., ParamTypeN], ReturnType]

26
цей typingматеріал переміщує всю мову пітона вгору.
javadba

1
@javadba - о, так, але я все ще не впевнений, на якому циферблаті ... До речі, - а як щодо , аргументів, що стосуються Callable[[Arg, Types, Here], ...]лише ключових слів і лише позиційних арг? Хіба вони не замислювалися над тим, щоб запровадити конвенцію у підписах типу для дзвінків? ;)*args**kwargs
Томаш Гандор

10

Ще один цікавий момент, який слід зазначити, - ви можете використовувати вбудовану функцію, type()щоб отримати тип вбудованої функції та використовувати її. Так ти міг

def f(my_function: type(abs)) -> int:
    return my_function(100)

Або щось такої форми


Натяк на тип може бути будь-яким, що ви хочете, але вони не завжди ліниво оцінювались. Крім того, чи дійсно ваша функція приймається лише builtin_function_or_methodяк my_function? Не вдалося б lambda? Користувацька функція або прив'язаний метод?
Томаш Гандор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.