2016-05-23 44 views
5

我想知道是否有可能使用自己的類而不是像listtuple這樣的內嵌類來解開星號。爲自己的類別提供明星解包

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 

哪些方法我必須爲了使拆包可能實現?

+6

你的'__iter__'應該在你的卡片上返回一個迭代器,而不是它們的長度。 – kindall

+1

可能重複[如何使類迭代?](http://stackoverflow.com/questions/19151/how-to-make-class-iterable) –

+1

@Rogalski我不同意這是一個重複的,它是不明顯的使它迭代解決了明星拆包問題(儘管它)。 –

回答

6

異常消息:*後

參數必須是一個序列

確實應該說,argument after * must be an iterable

因爲這個原因,經常將星型拆箱稱爲「可迭代拆箱」PEP 448 (Additional Unpacking Generalizations)PEP 3132 (Extended Iterable Unpacking)

編輯:看起來像這樣一直fixed for python 3.5.2 and 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 
+0

這個bug在1月份被修正了! https://github.com/python/cpython/blob/1123d9a07b4ab916e4d800308053980bcf8dbd57/Python/ceval.c#L5038-L5039 –

相關問題