如何让自定义类支持Python的*与**运算符?
自定义类字典类支持**运算符的实现
首先明确:Python没有专门对应展开的魔法方法(不同于*运算符对应__iter__)。要让自定义类支持前缀展开,必须让它符合映射类型协议——核心是能被识别为键值对集合,具体有两种实现方式:
方式1:继承标准映射抽象基类
最规范的做法是继承collections.abc.Mapping,它会强制你实现三个核心方法,其余映射相关方法(如keys()、items())会自动提供默认实现,天然支持**展开:
from collections.abc import Mapping class CustomDict(Mapping): def __init__(self, data=None): self._data = data or {} def __getitem__(self, key): return self._data[key] def __len__(self): return len(self._data) def __iter__(self): return iter(self._data) def __repr__(self): return f"CustomDict({self._data!r})"
使用示例:
def print_user(name, age): print(f"Name: {name}, Age: {age}") # 用**展开自定义字典 print_user(**CustomDict({"name": "Alice", "age": 30}))
方式2:手动实现映射核心方法
如果不想继承抽象基类,只需手动实现__getitem__和keys()方法(可选实现items()提升性能),就能让Python识别为可展开的映射:
class CustomDict: def __init__(self, data=None): self._data = data or {} def __getitem__(self, key): return self._data[key] def keys(self): return self._data.keys() # 可选:实现items()让字典转换更高效 def items(self): return self._data.items() def __repr__(self): return f"CustomDict({self._data!r})"
这个版本同样支持**展开,行为和标准字典一致。
自定义类元组类支持*运算符的实现
运算符的展开依赖__iter__魔法方法——只要你的类实现了__iter__并返回一个迭代器,就能用前缀展开。如果想让类更像元组,可以额外实现__getitem__和__len__:
class CustomTuple: def __init__(self, items): self._items = tuple(items) def __iter__(self): return iter(self._items) def __getitem__(self, idx): return self._items[idx] def __len__(self): return len(self._items) def __repr__(self): return f"CustomTuple({self._items!r})"
使用示例:
def calc_sum(a, b, c): return a + b + c print(calc_sum(*CustomTuple([10, 20, 30])))
内容的提问来源于stack exchange,提问作者dsz
相关产品推荐
相关产品推荐

