gpt4 book ai didi

python - 仅定义 '__getitem__' 方法的类如何支持 'in' 运算符?

转载 作者:行者123 更新时间:2023-11-28 21:32:06 31 4
gpt4 key购买 nike

如果我定义了以下内容:

Card = namedtuple('Card', ['rank', 'suit'])

class CardDeck():
ranks = [str(x) for x in range(2, 11)] + list('JQKA')
suits = 'spades diamonds clubs hearts'.split()

def __init__(self):
self._cards = [Card(rank, suit) for rank in self.ranks for suit in self.suits]

def __getitem__(self, index):
return self._cards[index]

如何in支持运算符,无需 __contains__定义了 dunder 方法。例如以下内容:

deck = CardDeck()
print(Card('2', 'hearts') in deck)

将输出:

True

有什么想法吗?

最佳答案

__getitem__当没有 __contains__ 时用作后备或 __iter__ method可用。请参阅Membership test operations section 表达式引用文档:

Lastly, the old-style iteration protocol is tried: if a class defines __getitem__(), x in y is True if and only if there is a non-negative integer index i such that x is y[i] or x == y[i], and no lower integer index raises the IndexError exception.

所以实际发生的情况是,Python 只是使用递增索引,在 Python 中,它看起来像这样:

from itertools import count

def contains_via_getitem(container, value):
for i in count(): # increments indefinitely
try:
item = container[i]
if value is item or value == item:
return True
except IndexError:
return False

这种处理扩展到所有迭代功能。未实现 __iter__ 的容器但一定要实现__getitem__仍然可以为它们创建一个迭代器(使用 iter() 或 C-API 等效项):

>>> class Container:
... def __init__(self):
... self._items = ["foo", "bar", "baz"]
... def __getitem__(self, index):
... return self._items[index]
...
>>> c = Container()
>>> iter(c)
<iterator object at 0x1101596a0>
>>> list(iter(c))
['foo', 'bar', 'baz']

当然,通过迭代进行的遏制测试并不是真正有效。如果有一种方法可以在不进行全面扫描的情况下确定某物是否是容器中的项目,请实现 __contains__方法来提供更好的实现!

对于一副卡片组,我可以想象只需返回 True当该项目是 Card 时实例应该足够了(假设 Card 类验证等级和花色参数):

def __contains__(self, item):
# a card deck contains all possible cards
return isinstance(item, Card)

关于python - 仅定义 '__getitem__' 方法的类如何支持 'in' 运算符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57028147/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com