Звезда распаковка для собственных классов
Мне было интересно, можно ли использовать распаковку по звездам с собственными классами, а не просто со встроенными list
а также tuple
,
class Agent(object):
def __init__(self, cards):
self.cards = cards
def __len__(self):
return len(self.cards)
def __iter__(self):
return self.cards
И уметь писать
agent = Agent([1,2,3,4])
myfunc(*agent)
Но я получаю:
TypeError: visualize() argument after * must be a sequence, not Agent
Какие методы мне нужно реализовать, чтобы сделать возможной распаковку?
1 ответ
Сообщение об исключении:
аргумент после * должен быть последовательностью
должен действительно сказать, argument after * must be an iterable
,
По этой причине часто распаковка звезд называется "повторяемой распаковкой". См. PEP 448 (Дополнительные обобщения распаковки) и PEP 3132 (Расширенная повторяемая распаковка).
Изменить: Похоже, это было исправлено для Python 3.5.2 и 3.6. В будущем он скажет:
аргумент после * должен быть повторяемым
Для того, чтобы распаковать звездочку, ваш класс должен быть повторяемым, то есть он должен определять __iter__
который возвращает итератор:
class Agent(object):
def __init__(self, cards):
self.cards = cards
def __len__(self):
return len(self.cards)
def __iter__(self):
return (card for card in self.cards)
затем:
In [11]: a = Agent([1, 2, 3, 4])
In [12]: print(*a) # Note: in python 2 this will print the tuple
1 2 3 4