用于和/或将事物组合在一起的Python语法?

时间:2010-06-25 02:26:55

标签: python syntax

我正在尝试设计一个验证表单字段的方案。我已经决定你可以将验证器列表传递到每个字段,例如

Field(validators=[email_validator, required_validator])

但后来我想,如果你想要or验证器,而不是and它们怎么办?例如,一个接受加拿大邮政编码,美国邮政编码的字段。当然,我可以创建一个可以接受的新验证器,但如果我想出一种允许用户选择的方法,它会很简洁。

是否有某种方法可以操作按位运算符?

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

或者我只是让事情变得过于复杂并让自己陷入困境?

4 个答案:

答案 0 :(得分:4)

Django通过使用Q个对象来解决这个问题,这些对象可以使用&|组合来创建更复杂的条件。模仿他们使用的东西可能是一个可以接受的解决方案。

答案 1 :(得分:1)

如果列表的项目是单个验证程序,或者and一起进行验证的列表,那么顶级列表会对所有项目执行or。你可以通过另一种方式做到这一点,当然,但通常是“并且按照惯例更严格地绑定”,所以这似乎是可以接受的。

更明确地说,您可以使用文字(引用)字符串'and''or'(以及可能'nand''nor'!)作为“运算符”的项目 - - 如果字符串的第一项(顶级或子字符串)是这样的运算符,它会说明如何处理所有其他字符串(默认值为'and')。

答案 2 :(得分:1)

您希望在验证程序类上实现 __或__(self,other) __以及__(self,other),它会动态返回一个知道如何的验证程序做适当的工作。因此,您基本上希望实现验证器,以便它们可以以这种方式动态组合(即,如果它们使用正则表达式,并且您可以对正则表达式的编写方式进行假设,则可以组合正则表达式适当地在您返回的新验证器中。)

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

答案 3 :(得分:1)

sqlobject使用类似这样的东西,这是一个例子:

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

这种方法的主要问题是运营商的优先级。它需要更多的括号来做得很好。一种更好的方法是使用And()和Or()函数并使用前缀表示法而不是中缀表示法。这样做的好处是,正在阅读代码的新程序员可以发现它。

在上面的示例中,我建议使用以下内容:

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

此列表中的所有验证器都隐含在一起。这使得琐碎的案例变得容易(琐碎的案例意味着“匹配所有这些验证器”)然后可能有相当复杂的表达式,例如:

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

当然,这只是一个建议。如图所示,使用&和|在某些系统中工作正常(Django,sqlobject)。在我的例子中你可以清楚地看到,复杂的案例在多层括号中存在问题,这是你应该考虑的权衡。