Проверка типов для аргументов http-post Python;Использование типов в качестве значений в словаре - PullRequest
2 голосов
/ 27 октября 2011

Для API, который я пишу, я хотел бы написать метод 'check_params', который гарантирует, что аргументы, передаваемые в теле запроса http-post, могут быть соответствующим образом типизированы.

Например, предположим, что я передаю аргумент 'широта'. Тогда

    'latitude'='thisisnotafloat'

должно выдавать ошибку, а

    'latitude'='43.21'

не должно выдавать ошибку.

Для обработки нескольких аргументов, есть что-то не так с созданием словаря с типами в качестве значений:

    required_types = {
            'arg1':str,
            'arg2':int,
            'arg3':str,
            'arg4':float
    }

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

    for arg, type_ in required_types.iteritems():
        try:
            type_(self.get_argument(arg))    #using tornado here to get body arg
        except:
            handle_invalid_type_error()

Кроме того, я мог бы хранить типы в виде строк и использовать функцию eval (). Например,

     required_types = {
            'arg1':'str',
            'arg2':'int',
            'arg3':'str',
            'arg4':'float'
    }

    for arg, type_ in required_types.iteritems():
        try:
            eval(type_)(self.get_argument(arg))  #using tornado here to get body arg
        except:
            handle_invalid_type_error()

Здесь есть явный победитель? Или другой превосходный подход?

Ответы [ 4 ]

2 голосов
/ 27 октября 2011

Рекомендованный («Pythonic») способ сделать это - просто выполнить преобразование, когда вам нужно, и вызвать ошибку, если она не удалась. Если в более поздней стадии программы не возникнет большой проблемы с ошибкой, я бы вообще не стал использовать метод check_params.

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

1 голос
/ 27 октября 2011

Ответ Дэвида был бы и моим общим советом.

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

  1. Вы не должны использовать голое предложение except. Он также будет отлавливать исключения, которые вы наверняка не хотите отлавливать здесь, например SystemExit. В данном примере голое предложение except также перехватывает KeyError (или что-то еще) в результате неудачного поиска аргумента, что, вероятно, приведет к довольно бесполезному сообщению об ошибке. Если типы, которые вы проверяете, являются встроенными типами Python, перехвата ValueError должно быть достаточно. Если ValueError недостаточно, except Exception почти всегда лучше, чем простое предложение except, так как он не поймает GeneratorExit, KeyboardInterrupt и SystemExit.

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

0 голосов
/ 12 марта 2013

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

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

Теперь, чтобы ответить на ваш вопрос:

Вы смотрели на эту суть: https://gist.github.com/anonymous/850704?

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

Если вы ищете что-то декларативное, вы можете взглянуть на https://pypi.python.org/pypi/voluptuous#show-me-an-example

0 голосов
/ 27 октября 2011

Есть ли шанс, что вы сможете использовать WTForms ?Если нет, то, возможно, стоит взглянуть на то, как он реализует валидаторы для вашего API.

...