Синтаксис Python для и / или объединения вещей? - PullRequest
3 голосов
/ 25 июня 2010

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

Field(validators=[email_validator, required_validator])

Но потом я подумал, что если вы хотите or валидаторы вместе, а не and их?Например, поле, которое принимает канадский почтовый индекс, или почтовый индекс США.Конечно, я мог бы просто создать новый валидатор, который мог бы принять и то, и другое, но было бы неплохо, если бы я мог найти способ, позволяющий пользователю выбирать.побитовые операторы?

Field(validators = required&(postal_code|zip_code))

Или я просто слишком усложняю ситуацию и стреляю себе в ногу?

Ответы [ 4 ]

4 голосов
/ 25 июня 2010

Django решает эту проблему, используя Q объекты, которые можно комбинировать, используя & и | для создания более сложных условий. Подражание тому, что они используют, вероятно, является приемлемым решением.

1 голос
/ 25 июня 2010

sqlobject использует что-то вроде этого, вот пример:

MyTable.select((MyTable.q.name == "bob") | (MyTable.q.age == 5))

Основная проблема в этом подходе - приоритет операторов.Для этого нужно гораздо больше скобок.Более хороший подход состоит в том, чтобы использовать функции And () и Or () и использовать префиксную нотацию вместо инфиксной нотации.Преимущество этого в том, что он может быть обнаружен новым программистом, который читает ваш код.

В вашем примере выше я бы предложил что-то вроде:

Field(validators=[required, Or(postal_code, zip_code)])

Где все валидаторы в этом спискеAnded вместе неявно.Это упрощает тривиальный случай (тривиальный случай означает «соответствовать всем этим валидаторам») и, следовательно, может иметь довольно сложные выражения, такие как:

Field(validators=Or(And(IsAmerica(), zip_code), 
                     And(Not(IsAmerica()), city))])

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

1 голос
/ 25 июня 2010

Вы хотели бы реализовать __ или __ (self, other) и __ и __ (self, other) в вашем классе валидатора, который динамически возвращает новый валидатор, который знает, как сделать подходящая работа. Итак, вы бы хотели реализовать свои валидаторы таким образом, чтобы их можно было динамически объединять таким образом (т. Е. Если они работают с регулярными выражениями и вы можете делать предположения о том, как пишутся регулярные выражения, вы можете комбинировать регулярные выражения соответственно в новом валидаторе вы возвращаете).

http://docs.python.org/reference/datamodel.html#emulating-numeric-types

1 голос
/ 25 июня 2010

Как насчет списка, элементы которого являются либо отдельными валидаторами, либо списками валидаторов, которые должны быть and объединены вместе - список верхнего уровня делает or для всех них.Вы можете сделать это по-другому, конечно же, в обход, но, как правило, «и крепче связывать» по соглашению, так что это кажется приемлемым.

Более явно, вы можете использовать элементы, которые являются литеральными (цитируемыми) строками 'and', 'or' (и, возможно, 'nand' и 'nor'!) Как «операторы» - если первый элемент строки (верхнего уровня или подстроки) является таким оператором, он говорит, что делать со всемидругие (по умолчанию может быть 'and').

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