Будет ли дополнительная статическая типизация полезной для Python API-дизайна или будет недостатком? (пример декоратора проверки типа) - PullRequest
3 голосов
/ 29 января 2012

Я давний разработчик Python и мне очень нравится динамическая природа языка, но мне интересно, выиграет ли Python от необязательной статической типизации. Было бы полезно иметь возможность применять статическую типизацию к API библиотеки, и каковы будут в этом недостатки?

Я быстро набросал декоратор, реализующий статический тип времени выполненияпроверка на pastebin , и она работает следующим образом:

# A TypeError will be thrown if the argument "string" is not a "str" and if 
# the returned value is not an "int"
@typed(int, string = str)
def getStringLength(string):
    return len(string)

Было бы целесообразно использовать такой декоратор в API-функциях библиотеки?С моей точки зрения, проверка типов не требуется во внутренней работе модуля библиотеки, специфичного для домена, но в точках соединения между библиотекой и ее клиентом может быть полезна простая версия проектирования по контракту с применением проверки типов.Особенно как тип принудительной документации, которая четко сообщает клиенту библиотеки, что он ожидает и возвращает.

Как в этом примере, где addObjectToQueue() и isObjectProcessed() предоставляются для использования клиентом и processTheQueueAndDoAdvancedStuff()является внутренней библиотечной функциейЯ думаю, что проверка типов может быть полезна для функций, обращенных наружу, но она будет раздутой и ограничит динамичность и полезность python, если будет использоваться во внутренних функциях.

# some_library_module.py

@typed(int, name = string)
def addObjectToQueue(name):
    return random.randint() # Some object id

def processTheQueueAndDoAdvancedStuff(arg_of_library_specific_type)
    # Function body here

@typed(bool, object_id = int)
def isObjectProcessed(object_id):
    return True

Каковы недостатки использования этоготехника будет?Каковы будут недостатки моей наивной реализации на pastebin ?

Я не хочу получать ответы на вопросы о преобразовании Python в язык со статической типизацией, но думаю о разработке API.конкретные плюсы / минусы.(переместите это на programmers.stackexchange.com, если считаете, что это не вопрос)

1 Ответ

7 голосов
/ 29 января 2012

Лично я не считаю эту идею привлекательной для Python. Конечно, это всего лишь мое мнение, но для контекста я скажу вам, что Python и Haskell, вероятно, являются моими двумя любимыми языками программирования - мне нравятся языки на обоих крайних уровнях спектра статической и динамической типизации.

Я вижу следующие основные преимущества статической типизации:

  1. Повышена вероятность того, что ваш код верен, как только компилятор его примет; если я знаю, что я пропустил свои значения через все операции, которые я вызвал таким образом, что тип результата одного всегда совпадает с типом ввода другого, а конечный тип результата - тот, который я хотел, это увеличивает вероятность того, что я Вы выбрали правильные операции. Эта точка глубоко обоснованной ценность, так как это только действительно имеет значение, если вы не тестируете очень много, что было бы плохо. Но это правда, что при программировании на Хаскеле, когда я сажусь и говорю: «Вот, готово! На самом деле я много времени провожу, хотя это почти никогда не относится к моему коду Python.
  2. Компилятор автоматически указывает на большинство мест, которые необходимо изменить, когда я делаю несовместимое изменение в структуре данных или интерфейсе (большую часть времени). Опять же, тесты все еще необходимы для того, чтобы убедиться, что вы уловили все последствия, но, по моему опыту, большую часть времени надоедает компилятору, что сильно упрощает такой рефакторинг; вы можете сразу перейти от реализации ядра рефакторинга к тестированию, что программа все еще работает нормально, потому что фактическая работа по выполнению всех изменений в потоке почти механическая.
  3. Эффективная реализация. Компилятор использует все свои знания о типах для оптимизации.

Предлагаемая вами система на самом деле не предоставляет ни одного из этих преимуществ.

  1. Написав программу, использующую вашу библиотеку, я до сих пор не знаю, содержит ли она какие-либо неверные типы использования ваших функций, пока не проведу обширное тестирование с полным охватом кода, чтобы выяснить, содержит ли какой-либо путь выполнения некорректный вызов.
  2. Когда я что-то реорганизую, мне нужно пройти много-много раундов «запустить полный набор тестов, найти исключение, найти, откуда оно пришло, исправить код», чтобы получить что-нибудь, например, обнаружение проблем компилятора статической типизации .
  3. Python по-прежнему будет вести себя так, как будто эти переменные могут быть чем угодно в любое время.

И чтобы получить даже это, вы пожертвовали гибкостью Python-duck-typing; недостаточно того, чтобы я предоставлял достаточно «подобный списку» объект, я должен фактически предоставить список.

Для меня такая статическая типизация - худшая из двух миров. Основным аргументом динамической типизации является «вы все равно должны тестировать свой код, так что вы также можете использовать эти тесты для выявления ошибок типов и избавления от необходимости обходить систему типов, когда она вам не помогает». Это может или не может быть хорошим аргументом в отношении действительно хорошей системы статических типов, но это абсолютно является убедительным аргументом в отношении слабой системы частичных статических типов, которая обнаруживает только ошибки типов во время выполнения. Я не думаю, что более приятные сообщения об ошибках (и это все, что вам действительно нужно, большую часть времени; ошибка типа, не обнаруженная на интерфейсе, почти наверняка приведет к более глубокому исключению в стеке вызовов), стоит потери гибкости.

...