我已经设置了一个名为Cell
的简单类class Cell:
def __init__(self, letter):
self.letter = letter
if letter == 'A' or letter == 'E' or letter == 'I' or letter == 'O' or letter == 'U' or letter == 'L' or letter == 'N' or letter == 'S' or letter == 'T' or letter == 'R':
self.points = 1
elif letter == 'D' or letter == 'G':
self.points = 2
elif letter == 'B' or letter == 'C' or letter == 'M' or letter == 'P':
self.points = 3
elif letter == 'F' or letter == 'H' or letter == 'V' or letter == 'W' or letter == 'Y':
self.points = 4
elif letter == 'K':
self.points = 5
elif letter == 'J' or letter == 'X':
self.points = 8
elif letter == 'Q' or letter == 'Z':
self.points = 10
else:
self.points = 0
现在我正在尝试为类编写__contains__
方法,所以如果我有一个Cell数组,我可以检查数组中是否包含某个字母的单元格
Tiles = []
Tiles.append(Cell("A")
Tiles.append(Cell("B")
Tiles.append(Cell("C")
Tiles.append(Cell("D")
Cell("A") in Tiles
应该返回True
但是我很困惑如何去做这个并且在网上或python文档中找不到任何帮助
答案 0 :(得分:0)
我正在尝试为类
编写__contains__
方法
不,你不是。这是您在问implementing a container时要问的问题,而不是被收录的问题。
您不会对如何实施__contains__
感到困惑 - 您只在容器上实现该功能,在这种情况下是列表。您对如何包含作品感兴趣。
您需要实施__eq__
(以及__hash__
和__ne__
,以获取更好的衡量标准)
我认为这是说明性的:
class Cell:
def __init__(self, thing):
self.thing = thing
def __eq__(self, other):
return other.thing == self.thing
a = [Cell(1)]
print Cell(1) in a
此处有更完整的示例:Elegant ways to support equivalence ("equality") in Python classes
我没有看到列表包含的确切工作的参考,但参考实现在line 437 here;基本上它循环遍历列表并检查提供的项目是否等于列表中的任何项目。
这就是为什么我们超载' ==
'通过重载__eq__
来实现等于运算符。
当然,这个过程是O(n)
(需要时间与列表中的项目数量成比例 - 我们必须在最坏的情况下检查每个项目)。字典或集合可以在O(1)
"常数"时间,但这需要将输入作为键进行散列。出于这个原因,通常习惯于在过载相等性时重载哈希函数,这样就不会出现意外行为。 __ne__
是python"不等于"运营商。 Overload this too
答案 1 :(得分:0)
如果s
是序列,则m in s
会返回bool
。现在,当s
类实现type(s)
方法时,__contains__
也可以是类似序列。
因此,obj in Tiles
与obj
中的成员资格无关,但与列表Tiles
中的成员资格无关。
其次,为什么Cell('A') in Tiles
在追加之前返回False
?因为它们是不同的对象。通过实现__eq__
方法,您可以引入新的语义,表明它们在满足时是相同的。
x = Cell('A')
y = Cell('A')
x is y # False, same as id(x) == id(y)
x == y # don't really know what that means
# now enriching semantics by __eq__
x == y # True/ False
如果要将这些对象用作键,则应实现__hash__
函数。但有一些警告。检查文档。