今更ながら関数呼び出しの**
にユーザー定義型を使えるようになっていたのに気づきました。
>>> 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
に見えました。