Как бороться с неправильными типами параметров в динамических языках? - PullRequest
2 голосов
/ 24 января 2011

Я не могу найти ответ на SO, но очень вероятно, что аргумент уже обсуждался.

Я пытаюсь написать программу небольшого размера, используя язык Python. Это мой первый «реальный» опыт работы с динамическим языком, и я бы предпочел сделать все правильно. Одна из практик, которую я бы попробовал применить с самого начала, это юнит-тестирование.

Как я могу быстро проверить, что параметры метода имеют правильный тип? Должен ли я сделать это?

С правильным типом я имею в виду, например, чтобы проверить, что метод, который работает с числами с плавающей запятой, не вызывается со строкой. В этом случае рассмотрите возможность того, что метод, очевидно, должен принимать даже целые числа, а не только с плавающей точкой.

Ответы [ 3 ]

3 голосов
/ 24 января 2011

Вы не должны проверять определенные типы.Согласно документам , вы должны просто использовать переданный объект по мере необходимости и дать пользователю возможность предоставить пользовательскую реализацию.

В зависимости от того, что делает ваша функция, это может бытьцелесообразно преобразовать аргументы в ожидаемый тип:

def my_func(a):
    a = float(a)
    # ...do stuff...

Другой отличный вариант - использовать hasattr() для проверки нужного члена перед его использованием.Это позволит вам вызвать полезное исключение вместо стандартной ошибки AttributeError.

3 голосов
/ 24 января 2011

Как я могу быстро проверить, что параметры метода имеют правильный тип?

Самый быстрый способ - ничего не делать.

Серьезно.Интерпретатор динамического языка (в данном случае Python) будет проверять намного быстрее, чем любой код, который вы когда-либо могли написать.Это просто вызовет исключение, и это все, что вам нужно сделать.Ничего.

Должен ли я это сделать?

Никогда не проверяйте для правильного типа.В общем, вы не можете этого сделать.

Допустим, у вас есть функция, для которой требуется "число"

def some_func( x ):
    assert isinstance(x, int)

Плохая политика.Ваша функция может работать долго или с плавающей точкой так же хорошо, как int.

assert instance( x, (int, long, float) )

Плохая политика.Вы все еще исключили комплекс.Действительно, вы также исключили decimal.Decimal и fractions.Rational, которые также являются действительными числами.

Путем «проверки типов» вы исключите допустимые типы.Единственное, что вы можете сделать, это предположить, что типы являются правильными, и изящно обработать исключение, когда кто-то «неправильно» использует вашу функцию или класс и предоставляет неправильные типы.

Ничего не делать.Программа должна полностью вылететь.

1 голос
/ 24 января 2011

Модульное тестирование с полным охватом - действительно единственный способ справиться с любой разработкой, основанной на динамических языках. Очевидно, что очень полезно иметь сильные тесты покрытия для статически типизированных языков, но, по моему опыту, это еще более важно, когда у вас динамическая типизация.

Если вы не охватили весь код, который может выполняться в ваших тестах, то действительно вы напрашиваетесь на неприятности. Таким образом, вы хотите использовать инструмент анализа покрытия в тандеме с вашими модульными тестами, чтобы доказать, что вы достигли всего своего кода.

Даже это не защитит от всех ловушек - ваши тесты действительно должны использовать все возможные ошибки ввода данных, которые может получить ваша программа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...