Как я могу указать тип функции в моих подсказках типа?

Я хочу использовать подсказки типа в моем текущем проекте 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, но не смог найти подсказку типа функции там.

5 ответов

Как отметил @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]

Еще один интересный момент, который стоит отметить, это то, что вы можете использовать встроенную функцию type() чтобы получить тип встроенной функции и использовать его. Так что вы могли бы иметь

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

Или что-то в этой форме

Мой конкретный вариант использования этой функциональности заключался в том, чтобы включить расширенное завершение кода в PyCharm. С использованием Callableне заставил PyCharm предположить, что у объекта есть атрибут, чего я и хотел в данном случае.

Я наткнулся на модуль и ..

from types import FunctionType

позволил мне аннотировать объект с помощью FunctionTypeи, вуаля, теперь PyCharm предполагает, что мой объект имеет .__code__атрибут.

ОП не понял, почему эта подсказка типа была им полезна. Callable, безусловно, работает для всего, что реализует .__call__()но для дальнейшего разъяснения интерфейса я отправляю typesмодуль.

Облом, что Python нужно два очень похожих модуля.

В python3 работает без import typing:

      def my_function(other_function: callable):
    pass

Самое простое и красивое решение:

      def f(my_function: type(lambda x: None)):
    return my_function()

Это можно доказать следующим образом:

      def poww(num1, num2):
    return num1**num2
    
print(type(lambda x: None) == type(poww))

и вывод будет: True

Другие вопросы по тегам