gpt4 book ai didi

python - 如何将 random.choice 应用于我的自定义类?

转载 作者:太空宇宙 更新时间:2023-11-03 15:52:05 25 4
gpt4 key购买 nike

我正在阅读Fluent Python

代码1-1,这里构造了一个namedtuples类,实现了__len____getitem__

import collections

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


class FrenchDeck:
ranks = [str(n) for n 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 __len__(self):
return len(self._cards)

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

但后来作者使用 random.choice 从牌组中选择一张牌

from random import choice
deck = FrenchDeck()
choice(deck)

这是如何运作的?我不认为 deck 是一个序列。

最佳答案

实现 __getitem__ 使您的类可迭代。观看:

>>> class LegacyIterable(object):
... def __init__(self):
... self._list = ['a', 'b', 'c']
... def __getitem__(self, item):
... return self._list[item]
...
>>> x = LegacyIterable()
>>> for e in x:
... print e
...
a
b
c

如果一个类没有 __iter__ 方法但有 __getitem__ 方法,Python 在被迫这样做时,会从一个试图访问它的实例的实例构造一个迭代器通过 __getitem__ 获取元素。它从索引 0 开始,并在抛出 IndexError 时结束。

但是,由于 LegacyIterable 实例没有 __len__ 方法,因此它们在形式上还不算作序列和 random.choice会提示

TypeError: object of type 'LegacyIterable' has no len()

但是,一旦我们给它一个 __len__ 方法,实例就被视为序列,根据其文档,这就是 random.choice 想要的。

>>> LegacyIterable.__len__ = lambda x: 3
>>> choice(LegacyIterable())
'c'

choice(self, seq) method of random.Random instance
Choose a random element from a non-empty sequence.

关于python - 如何将 random.choice 应用于我的自定义类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46049062/

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