2.6から、**に任意のmappingを使える!


今更ながら関数呼び出しの**にユーザー定義型を使えるようになっていたのに気づきました。

>>> from collections import *
>>> class X(Mapping):
...     def __getitem__(self, k): return 0
...     def __iter__(self): return iter("xyz")
...     def __len__(self): return 0
...
>>> "{x}".format(**X())
'0'
>>> import inspect
>>> inspect.getmro(X)
(<class '__main__.X'>, <class '_abcoll.Mapping'>, <class '_abcoll.Sized'>, <clas
s '_abcoll.Iterable'>, <class '_abcoll.Container'>, <type 'object'>)
>>> # dictのサブクラスではない!
>>> "{a}".format(**X())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'a'



ただし、{a}".format(**X())を見ればわかるように、__getitem__が定義されているだけではダメで、

「mappingとして評価出来なければならない(expression must evaluate to a mapping)」
らしいです。



What’s New in Python 2.6 窶鐀 Python v2.6.4 documentationから飛んだ、Issue 1686487: Allow any mapping after ** in calls - Python trackerのパッチを見ると、


dict.updateの引数として渡せなきゃダメみたいです。


全くどうでもいいことですが、getmro が一瞬getmoroに見えました。