如何实现自定义的星星运算符(**
)来解包,类似于__iter__
与单星运算符(*
)的工作方式?
例如:
class PlayerManager(object):
def __init__(self, players=None):
self.players = players or []
# Made up method to support ** operator
def __dict_iter__(self):
for player in self.players:
yield get_steamid(player), player
def print_players(**players):
print(players)
player_manager = PlayerManager([list, of, players])
print_players(**player_manager)
输出:
{
'STEAM_0:0:02201': <Player object at 0x0000000000>,
'STEAM_0:0:10232': <Player object at 0x0000000064>,
'STEAM_0:0:73602': <Player object at 0x0000000128>
}
2条答案
按热度按时间ix0qys7i1#
就像@ShadowRanger说的,实现Mapping。下面是一个例子:
程序输出:
huwehgph2#
实现
Mapping
ABC。从技术上讲,语言文档没有指定使用哪些Mapping
方法,因此假设您只需要当前实现使用的某个子集是一个坏主意。它所说的全部内容是:如果语法**expression出现在函数调用中,则expression必须计算为Map,其内容被视为附加的关键字参数。如果关键字同时出现在expression和显式关键字参数中,则会引发TypeError异常。
因此,如果您实现
Mapping
ABC,您肯定拥有正确的接口,无论它是否依赖于.items()
,直接迭代和__getitem__
调用等。仅供参考,CPython 3.5中的行为完全取决于您如何实现
Mapping
(如果你继承了dict
,它会使用一个优化的路径直接访问dict
内部,如果你没有,它会迭代.keys()
并查找每个键)。实现整个ABC。由于继承了Mapping
ABC及其父代的默认实现,这可以通过以下方式完成:在某些情况下,你继承的默认实现可能不是最佳的(例如,
items
和values
会做一些涉及迭代和查找的半邪恶的事情,其中直接访问器可能会更快,这取决于内部结构),所以如果你将其用于其他目的,我建议用优化版本覆盖它们。