为Python类实现“包含”时出错

2024-09-30 01:26:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图实现contains,这样它就可以用于python对象中的任何一个属性。我能够成功地实现“==”和大多数其他比较运算符,但是“in”给我带来了问题:

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)
         def __contains__(self,other):
             return Comparator(self.name,other,operator.contains)
    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)

# the line below works fine!
print list(mytable.filter(Row.val3 == 7))

# this line below does not work
print list(mytable.filter("h" in Row.val4))
# TypeError: 'bool' object is not callable

# this line also does not work
print list(mytable.filter(Row.val4 in "hello world"))
# TypeError: 'in <string>' requires string as left operand, not instance

Tags: nameinselfreturndefoperatorclassrows
2条回答
  1. 对于filter,必须传递可调用的,而不是布尔值
  2. row_obj.val4是类RowItem的实例,而不是{}类的__contains__方法所期望的字符串

感谢凯文在评论中回答了这一点。问题是^{cd1>}(^{cd2>}方法)将结果强制为布尔值,而不是其他逻辑比较运算符(^{cd3>}、^{cd4>},以及其他)。

这似乎是因为向后兼容性。 此处的详细信息: https://mail.python.org/pipermail/python-dev/2013-July/127297.html

解决这一问题的一种方法是创建一个新方法(例如,包含\uu):

尝试类似的方法(这是一个坏例子,因为包含将在该代码中工作:

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)
         def contains_(self,other):
             return Comparator(self.name,other,operator.contains)
    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)

而不是:

^{pr2}$

当然,在尝试执行“in”时,您需要执行以下操作:

^{pr3}$

而不是:

^{pr4}$

相关问题 更多 >

    热门问题