Tuple[Callable, Any, ...]
Опубликовано 29 January 2018 в Python
Подсказки с типами могут сильно помочь в работе с большим проектом на Питоне. Тем не менее, иногда они требуют рефакторинга кода. Я писал об этом в прошлом году в этой статье, но тогда я не смог найти хорошего примера иллюстрирующего то, что я хочу сказать.
Взгляните на этот код:
def process(workflow_step):
func = step[0]
args = step[1:]
return func(*args)
Что можно понять о типах из этого кусочка? То, что workflow_step
- это последовательность, первый элемент которой - Callable
object, а остальные элементы, если таковые имеются, аргументы для этого вызываемого объекта. Предположим, что workflow_step
- Tuple
. Проблема в том, что тип (Tuple) -> Any
для этой функции слишком общий и неинформативный. Можем мы вызвать ее с пустым таплом? (1, 2, 3)
пройдет?
(Tuple[Callable, Any, ...]) -> Any
- много лучше. Вот только, такое определение не поддерживается синтаксисом библиотеки типов Питона. В простых случаях, одним из возможных выходов из этой ситуации будет использование типов вроде таких Union[Tuple[Callable], Tuple[Callable, Any]]
или чего-то подобного. В более сложных случаях единственным возможным решением будет рефакторинг.
Есть много вариантов, как это сделать. К примеру, для функции из примера я использовал NamedTuple
.
class WorkflowStep(NamedTuple):
callable # type: Callable
args # type: Tuple
def process(workflow_step):
# type: (WorkflowStep) -> Any
return step.callable(args. args)
Возможно, это не лучший кусок кода, который вы видели, тем не менее, он на много информативнее и структурированнее предыдущего варианта.
Возник вопрос? Мне всегда можно написать в Twitter: avkorablev