Я должен проверить типы аргументов конструктора (и в других местах также)?

Как насчет чего-то простого, например:

sleep "$threshold"
grep -q 'PATTERN' "$log_file" && { echo "Clear"; exit; }
echo "Error"

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

12
задан Nathan Kleyn 13 April 2013 в 21:06
поделиться

7 ответов

Простой ответ нет, используйте Полиморфизм, Исключения и т.д.

  1. В случае аргументов конструктора, являющихся неправильного типа, исключение будет выдано при выполнении кода, которые зависят s от параметра, являющегося конкретного типа. Если это - странная, зависящая от домена вещь, повысьте свое собственное Исключение. Окружите блоки кода, которые, вероятно, перестанут работать с попыткой - кроме и обработают ошибки. Таким образом, лучше использовать Обработку исключений. (То же идет для аргументов функции),

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

В Python Вы рассматриваете программистов как умных существ!! Просто зарегистрируйте свой код хорошо (сделайте вещи очевидными), повысьте Исключения в соответствующих случаях, напишите полиморфный код и т.д. Оставьте Обработку исключений (где это является соответствующим только) / ошибки в конструкции к клиентскому коду.

Предупреждение
Отъезд Обработки исключений клиентам не означает, что необходимо зажать много ошибок мусора в невольном пользователе. Если вообще возможный, обработайте исключения, которые могли бы произойти из-за плохой конструкции или любой другой причины в Вашем коде самом. Ваш код должен быть устойчивым. Где для Вас невозможно обработать ошибку, вежливо сообщите, что пользователь/клиент кодирует программиста!

Примечание:
В целом, неверные аргументы конструктору не что-то, о чем я волнуюсь слишком много.

10
ответ дан 2 December 2019 в 05:42
поделиться

Проверьте все, что Вы любите, просто необходимо быть явными. Следующим примером является конструктор от модуля в стандартной библиотеке - это проверяет extrasaction аргумент:

class DictWriter:
  def __init__(self, f, fieldnames, restval="", extrasaction="raise",
               dialect="excel", *args, **kwds):
      self.fieldnames = fieldnames    # list of keys for the dict
      self.restval = restval          # for writing short dicts
      if extrasaction.lower() not in ("raise", "ignore"):
          raise ValueError, \
                ("extrasaction (%s) must be 'raise' or 'ignore'" %
                 extrasaction)
      self.extrasaction = extrasaction
      self.writer = writer(f, dialect, *args, **kwds)
4
ответ дан 2 December 2019 в 05:42
поделиться

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

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

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

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

11
ответ дан 2 December 2019 в 05:42
поделиться

Это часто - хорошая вещь сделать. Проверка явные типы, вероятно, не настолько полезна в Python (как другие сказали), но проверяющий на легальные значения может быть хорошая идея. Причина это - хорошая идея, состоит в том, что программное обеспечение перестанет работать ближе к источнику ошибки (это следует за Сбоем Быстрый Принцип). Кроме того, проверки действуют как документация другим программистам и Вам. Еще лучше это - "исполняемая документация", которая хороша, потому что это - документация, которая не может лечь.

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

def my_sqrt(x):
    assert x >= 0, "must be greater or equal to zero"
    # ...

Утверждением Ваших аргументов является Дизайн своего рода бедного человека Контракта. (Вы хотели бы искать Дизайн Контракта; это интересно.)

1
ответ дан 2 December 2019 в 05:42
поделиться

AFAIU, Вы хотите удостовериться, что некоторые объекты ведут себя ("следуют за интерфейсом") в более раннее время, чем то из фактического использования. В Вашем примере Вы хотите знать, что объекты являются соответствующими во время создания экземпляра, не, когда они будут на самом деле использоваться.

Учет того факта, что мы говорим Python здесь, я не предложу assert (что, если python -O или переменная среды PYTHONOPTIMIZE установлена на 1 когда Ваши прогоны программы?) или проверяющий на определенные типы (потому что это излишне ограничивает типы, которые можно использовать), но я предложу рано тестировать функциональность, что-то вдоль строк:

def __init__(self, a_number, a_boolean, a_duck, a_sequence):

    self.a_number= a_number + 0

    self.a_boolean= not not a_boolean

    try:
        a_duck.quack
    except AttributeError:
        raise TypeError, "can't use it if it doesn't quack"
    else:
        self.a_duck= a_duck

    try:
        iter(a_sequence)
    except TypeError:
        raise TypeError, "expected an iterable sequence"
    else:
        self.a_sequence= a_sequence

Я использовал try… except… else в этом предложении, потому что я хочу установить членов экземпляра, только если тест успешно выполнился, даже если код изменяется или увеличивается. Вы не должны делать этого так, очевидно.

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

1
ответ дан 2 December 2019 в 05:42
поделиться

"Если я не сделаю и установлю участников объекта на аргументы, то это вызовет проблемы позже".

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

  • Разве это не будет работать вообще? Это, для чего блоки попытки/кроме.

  • Это будет вести себя "странно"? Это действительно редко, и ограничено типами "попадания" и операторами. Стандартным примером является подразделение. Если Вы ожидали целые числа, но стали с плавающей точкой, то подразделение не может сделать то, что Вы хотели. Но это фиксируется с//, по сравнению с / операторы деления.

  • Это будет просто неправильно, но все еще, казаться, будет завершаться? Это действительно редко, и потребовало бы симпатичного тщательно обработанного типа, который использовал стандартные имена, но сделал нестандартные вещи. Например,

    class MyMaliciousList( list ):
        def append( self, value ):
            super( MyMaliciousList, self ).remove( value )
    

Кроме этого, трудно иметь вещи "проблемы причины позже". Обновите свой вопрос с определенными примерами "проблем".

0
ответ дан 2 December 2019 в 05:42
поделиться

Как плитка говорит, ответ является почти всегда "нет". В Python Вы обычно не заботитесь, что параметр является определенным типом, а скорее что он ведет себя как определенный тип. Это известно как "Утиный Ввод". Существует два способа протестировать, ведет ли параметр себя как данный тип: (1) можно использовать его, как будто это вело себя, как Вы ожидаете и выдаете исключение, когда/если это не сделает или (2) можно определить интерфейс, который описывает, как тот тип должен вести себя и протестировать соответствие с тем интерфейсом.

zope.interface является моей предпочтенной интерфейсной системой для Python, но существует несколько других. С любым из них Вы определяете интерфейс, затем объявляете, что данный тип соответствует тому интерфейсу, или определите адаптер, который превращает Ваш тип во что-то, что действительно соответствует тому интерфейсу. Можно затем утверждать (или протестировать, как Вы желаете), что параметры обеспечивают (в zope.interface терминологии) тот интерфейс.

0
ответ дан 2 December 2019 в 05:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: