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

2024-04-18 04:36:29 发布

您现在位置:Python中文网/ 问答频道 /正文

例如:

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类)继承而实现这个功能吗?或者这只是我无法使用的秘密魔法?你知道吗


Tags: 实例keytestself列表returnobjectdef
2条回答

您需要重写__iter____getitem__。下面是一个使用__iter__的示例:

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

a,b = Test()

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

有关使用__getitem__的示例,请参见jornsharpe的优秀答案。你知道吗

PerPEP-234,它定义迭代器(emphasis mine):

An object can be iterated over with "for" if it implements __iter__()or __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

相关问题 更多 >