简体   繁体   English

为Python类实现“和”?

[英]Implementing “and” for Python class?

I have code similar to this: 我有类似这样的代码:

import operator
class Comparator:
     def __init__(self,fieldName,compareToValue,my_operator):
         self.op = my_operator
         self.field = fieldName
         self.comparedTo = compareToValue
     def __call__(self,row):
         my_row_val = getattr(row,self.field)
         return self.op(my_row_val,self.comparedTo)


class Row:
    class RowItem:
         def __init__(self,name):
              self.name = name
         def __eq__(self,other):
             return Comparator(self.name,other,operator.eq)
    val1 = RowItem("val1")
    val2 = RowItem("val2")
    val3 = RowItem("val3")
    val4 = RowItem("val4")
    def __init__(self, val1, val2, val3, val4):
        self.val1 = val1
        self.val2 = val2
        self.val3 = val3
        self.val4 = val4
    def __str__(self):
        return str([self.val1,self.val2,self.val3,self.val4])
    def __repr__(self):
        return str(self)


class MyTable:
    def __init__(self,rows):
        self.rows = rows
    def filter(self,condition):
        for row in self.rows:
            if condition(row):
               yield row

rows = [Row(1,2,3,"hello"),Row(1,2,7,"cat"),Row(1,2,3,"hi"),Row(7,7,7,"foo")]
mytable = MyTable(rows)

I can successfully run filtering tests, for example: 我可以成功运行过滤测试,例如:

print list(mytable.filter(Row.val3 == 7))
# prints [[1, 2, 7, 'cat'], [7, 7, 7, 'foo']]
print list(mytable.filter(Row.val2 == 2))
# prints [[1, 2, 3, 'hello'], [1, 2, 7, 'cat'], [1, 2, 3, 'hi']]

but when I try to use an and it does not work as I would like: 但是当我尝试使用它and它不能按我的意愿工作时:

print list(mytable.filter((Row.val3 == 7) and (Row.val2 == 2)))
# this only evaluates the second condition, instead of both conditions, printing:
# [[1, 2, 3, 'hello'], [1, 2, 7, 'cat'], [1, 2, 3, 'hi']]

How can I get the and to work correctly? 我怎样才能正常工作?

You cannot hook into the and and or logical operators, because they short-circuit ; 你不能挂钩到andor逻辑运算符,因为它们短路 ; the left-hand expression is evaluated first and if the result of that expression determines the outcome, the right-hand expression is never evaluated even. 首先评估左手表达式,如果该表达式的结果确定结果,则永远不会评估右手表达式。 The operation returns the value of the last expression evaluated. 该操作返回最后一个表达式的值。

In your case, the (Row.val3 == 7) and (Row.val2 == 2) expression evaluates (Row.val3 == 7) first, and as that returns an instance without any specific hooks to say otherwise, it is considered a true value , so the result of the right-hand expression is then returned. 在您的情况下, (Row.val3 == 7) and (Row.val2 == 2)表达式首先计算(Row.val3 == 7) ,因为它返回一个没有任何特定钩子的实例,否则,它是被认为是真值 ,因此返回右手表达式的结果。

You can use & and | 可以使用&| (bitwise AND and OR) operators here, these delegate to the object.__and__ and object.__or__ hooks. (按位AND和OR)运算符在这里,它们委托给object.__and__object.__and__object.__or__钩子。 This is what ORM libraries like SQLAlchemy do. 这就像SQLAlchemy那样的ORM库。

The corresponding operator functions are operator.and_ and operator.or_ . 相应的operator函数是operator.and_operator.or_

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM