2011-01-24 3 views
2

Я не могу найти ответ на SO, но очень вероятно, что аргумент уже обсуждался.Как бороться с неправильными типами параметров в динамических языках?

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

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

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

ответ

3

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

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

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

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

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

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

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

Bad политики. Ваша функция может работать долго или плавать так же хорошо, как и int.

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

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

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

Самый изящный способ обработки TypeError?

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

1

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

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

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

3

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

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

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

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

+2

«В идеале» можно удалить. Вы не проверяете типы. Тесты переводчиков для типов. Вы просто используете объект. –