我可以创建一个可以解压缩的类吗?

时间:2016-07-12 13:16:01

标签: python python-2.7 iterator

例如:

x = (1, 2)
a,b = x

现在我希望在x是某个类的实例而不是列表或元组的情况下实现此目的。简单地覆盖__getitem____getslice__无效:

class Test(object):
    def __getitem__(self, key):
        return 1

a,b = Test()

会产生ValueError: too many values to unpack。我是否可以在不继承listtuple(或其各自的UserX类)的情况下完成此项工作?或者这只是我无法使用的一些引擎盖下的魔法?

2 个答案:

答案 0 :(得分:4)

您需要覆盖__iter____getitem__。以下是使用__iter__的示例:

class Test(object):
    def __iter__(self):
        return iter([1, 2])

a,b = Test()

注意,__iter__需要返回迭代器。最简单的方法是将数据结构包装在iter中,或者让它从生成器中生成。

有关使用__getitem__的示例,请参阅jonrsharpe的优秀答案。

答案 1 :(得分:4)

Per PEP-234,定义迭代器(强调我的):

  

如果对象实现,则可以使用“for”迭代对象   __iter__() __getitem__()

可以使用__getitem__执行此操作,但必须抛出IndexError以指示您何时到达终点。你看到too many values to unpack,因为Python没有办法告诉它已完成迭代你的对象。

这样可行:

class Test(object):
    def __getitem__(self, key):
        if key > 1:
            raise IndexError
        return 1 

使用中:

>>> t = Test()
>>> a, b = t
>>> a
1
>>> b
1
>>> t[2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __getitem__
IndexError