Python: 重载元组多重赋值功能?

10 投票
1 回答
1150 浏览
提问于 2025-04-16 23:56

我自己做了一个基于字典的命名元组类:

class t(dict):
   def __getattr__(self, v):
      try:
         return self[v]
      except KeyError:
         raise AttributeError("Key " + str(v) + " does not exist.")
   def __init__(self, *args, **kwargs):
      for source in args:
         for i, j in source.items():
            self[i] = j
      for i, j in kwargs.items():
         self[i] = j

>>> thing = t(cow=10, moo='moooooooo')
>>> thing.cow
10
>>> thing.moo
'moooooooo'

使用字典的原因是我可以使用**展开运算符,同时整个东西也可以像字典一样转成JSON格式。初始化中的双重循环是为了在反序列化后能立即从字典中重建这个对象。

我唯一缺少的就是元组那种可以多重赋值的功能,比如说:

>>> thing = (1, 3, ('blargh', 'mooo'))
>>> a, b, (c, d) = thing
>>> a
1
>>> b
3
>>> c
'blargh'
>>> d
'mooo'

有没有办法让我自己的自定义数据类型也能实现这种行为?有没有什么函数可以重写,或者有什么类可以继承,以便获得这种功能?

1 个回答

12

没错。你需要实现一下 __iter__() 这个方法。

class unpackable_dict(dict):
    def __iter__(self):
        return (self[key] for key in sorted(self.keys()))

d = unpackable_dict(a=1, b=2)
a, b = d

通常情况下,你不能像解包元组那样从字典中解包值,原因是字典里的元素没有固定的顺序。我用了一种生成器表达式来按照键的排序顺序取出字典里的项目。不过,你也可以考虑使用 OrderedDict,它会保持元素的插入顺序。

撰写回答