Обычная/хорошая практика - проверить значения типа в Python?

Является ли распространенным явлением Python проводить тестирование значений типа при работе в режиме ООП?

class Foo():
    def __init__(self,barObject):
        self.bar = setBarObject(barObject)

    def setBarObject(barObject);
        if (isInstance(barObject,Bar):
            self.bar = barObject
        else:
            # throw exception, log, etc.

class Bar():
    pass

Или я могу использовать более свободный подход, например:

class Foo():
    def __init__(self,barObject):
        self.bar = barObject

class Bar():
    pass

Ответ 1

Нет, на самом деле он в целом распространен, чтобы не тестировать значения типа, как в вашем втором подходе. Идея состоит в том, что клиент вашего кода (т.е. Какой-либо другой программист, который использует ваш класс) должен иметь возможность передавать любой объект, имеющий все соответствующие методы или свойства. Если это не экземпляр какого-то определенного класса, это прекрасно; ваш код никогда не должен знать разницу. Это называется утиным типом, из-за пословицы "Если он сходит с ума, как утка, и летает как утка, это может быть и утка" (ну, это не настоящая поговорка, но я понял суть этого)/p >

Одно место, которое вы увидите это много, находится в стандартной библиотеке с любыми функциями, которые обрабатывают ввод или вывод файла. Вместо того, чтобы требовать фактический объект file, они будут использовать все, что реализует метод read() или readline() (в зависимости от функции), или write() для записи. Фактически вы будете часто видеть это в документации, например. с tokenize.generate_tokens, о котором я сейчас только что узнал сегодня:

Генератору generate_tokens() требуется один аргумент, readline, который должен быть вызываемым объектом, который предоставляет тот же интерфейс, что и метод readline() встроенных объектов файла (см. раздел Объекты файлов). Каждый вызов функции должен возвращать одну строку ввода в виде строки.

Это позволяет вам использовать объект StringIO (например, файл в памяти) или что-то более странное, как диалоговое окно, вместо реального файла.

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

Ответ 2

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

Однако, кажется, пустая трата времени (как для записи, так и для запуска программы), чтобы проверить тип ввода, который программа генерирует независимо от ввода. Как и в строго типизированном языке, тип проверки не имеет значения для защиты от ошибки программиста.

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

Ответ 3

Если ваша альтернатива проверке типа - это else, которая содержит обработку исключений, тогда вам следует подумать о том, что утка набирает один уровень, поддерживая столько объектов с помощью методов, которые требуются вам от ввода, и работая внутри попытки. Затем вы можете исключить (и, если возможно, конкретно) это. Окончательный результат не будет отличаться от того, что у вас есть, но гораздо более универсальным и Pythonic.

Все остальное, что нужно было сказать о фактическом вопросе, будь то обычная/хорошая практика или нет, я думаю, что Давида отлично ответили.

Ответ 4

Я согласен с некоторыми из приведенных выше ответов, поскольку я вообще никогда не проверяю тип от одной функции к другой.

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