Когда Гвидо ван Россум впервые написал, что он подумывает о том, чтобы попробовать включить в Питон опциональное описание типов аргументов и значений функций, а потом долго гасил флейм, я сразу эмоционально принял сторону ярых противников этой штуки. В конце концов, у нас же есть duck typing! И всякая идея декларировать тип объекта отдельно от того, что он и так сам собой представляет, ведет ко всем неудобствам сидения на двух стульях и выполнению двойной работы. И вообще — ересь какая-то :-)
Однако в сегодняшнем его посте о подготовке Питона 3000, я узнал, что решение о включении этой опциональной типизации (которая называется "function annotations") таки принято.
Тем не менее, вместо того, чтобы идти в угол плакать, я решил все же прочитать, что же оно на самом деле собой представляет: PEP 3107, Function Annotations. Все, оказывается, гораздо веселей, чем можно было думать! Для тех, кто не пойдет читать (знаю, сам такой :-) ), перескажу вкратце, что мне больше всего понравилось.
"Аннотации" — это выражения, которые как-то описывают параметры и возвращаемое значение функции, типа такого:
def func(a: Integer, b: String) -> Sequence:
# ...
Но это не типы!
Во-первых, они не просто опциональны, а совсем опциональны. То есть, их не только не обязательно указывать, как таковые, но и даже если они указаны, в функцию все равно можно передавать все что угодно, как и раньше. Их роль — исключительно добавочная, для того, чтобы всякие сторонние тулзы могли делать больше предположений о коде и предоставлять лучший сервис. Речь идет о дополнении кода и подсказках в редакторе IDE, внешних проверяльщиках корректности кода и т.д. Цитируя PEP, аннотации "не имеют никакого собственного смысла; смысл определяется только сторонней библиотекой".
Во-вторых (после чего я теперь считаю, что аннотации — вещь!), они не обязаны быть похожими на типы. Это может быть любое выражение: число, строка, вычисление, ну и тип тоже, конечно. Можно например написать:
def show(f: 'Filename or a file-like object'):
# ...
И аннотацией к параметру "f" будет просто поясняющий текст. Также, насколько я понимаю, можно сказать "возвращаемое значение функции "process" предполагается таким же, как у функции "prepare":
def process() -> prepare.func_annotations['return']:
# ...
Короче говоря, это не какая-то страшная "типизация", это просто такая структурированная документация, дающая полезные подсказки сторонним тулзам.
Кстати, первая альфа Питона 3000 обещается в этом августе. А релиз — в следующем августе. Пора начинать привыкать :-).
Комментарии: 38
Это правильно. Я, например, начав разбираться с Django и Питоном, был неприятно удивлен тем, что не могу понять, что делает метод, что от него ожидать и чего в него можно передать, просто глянув на заголовок. Все таки строгая типизация и variant там, где нужно - это самый правильный подход IMHO.
В мире С, C++ Java, PHP и т.п. для этих целей используется формат Doxygen (http://www.stack.nl/~dimitri/doxygen/)). Кстати, на их сайте заявлена поддержка и питона ;).
Что заставляет придумывать новый подход и отказываться от проверенного решения?
Основная мотивация "почему не docstring'и", насколько я понял, в том, что docstring'и тогда получатся слишком сложными и слишком для многих вещей. С аннотациями проще работать — их не надо парсить отдельно. А сейчас да, именно в докстрингах все такое и принято хранить.
ЧТо значит "не надо парсить отдельно"? Как я понял этим занимаются редакторы и IDE, а Pyton'овский парсер их будет просто игнорировать. А для IDE особой разницы нет что аналицировать аннотации или Doxygen. Кроме того, формат Doxygen позволяет позволяет описать работу метода, в большинстве случаев простого указания типов и кратиких описаний параметров и возвращаемого результата будет не достаточно.
2dacuan.
Питоновский парсер их не будет игнорировать, он их будет засовывать в метаданные объекта. Примерно так же как сейчас он хранит докстринги в __doc__. То есть сам Python не будет делать никаких выводов из аннотаций, но будет их хранить структурированно. И дополнительно парсить докстринги, чтобы выдернуть из них информацию о параметре, не потребуется.
Когда прочитал PEP, сама идея мне очень понравилась. С другой стороны, это лишь отличная потенциальная возможноть. Реальная польза будет целиком и полностью зависеть от тех самых третьесторонних библиотек, которые эти аннотации должны использовать. В Python 3.0, и вероятно, в несколько следующих версий тоже, ни одна из таких библиотек не войдет.
doxygen может и неплох для си, но для питона лучче epydoc
@Максим
т.е., доводя до конечной точки можно сказать, что аннотации == докстринги для параметров функций. Что правильно. Отдельное спасибо Ивану за разъяснение.
Alex Lebedev: