Which objects are expanded by double-star ** operator?

Peter Otten __peter__ at web.de
Mon Jun 7 18:03:36 EDT 2010


kkumer wrote:

> 
> I have to merge two dictionaries into one, and in
> a "shallow" way: changing items should be possible
> by operating either on two parents or on a
> new dictionary. I am open to suggestions how
> to do this (values are always numbers, BTW), but
> I tried to do it by creating a dict-like class that just
> forwards all calls to the two parent dicts, see below.
> 
> It works, but one important thing is missing. I
> am not able to expand new dictionary with
> double-star operator ** to use it as a
> set of keyword arguments of a function.
> I googled a bit, but was unable to find what
> property must an object have to be correctly
> treated by **.

The following experiment shows that you only need to implement a keys() and 
__getitem__() method.

$ cat kw.py
class A(object):
    def keys(self): return list("ab")
    def __getitem__(self, key):
        return 42

def f(**kw):
    print(kw)

f(**A())
$ python kw.py
{'a': 42, 'b': 42}

However, if you have A inherit from dict...

$ cat kwd.py
class A(dict):
    def keys(self): return list("ab")
    def __getitem__(self, key):
        return 42

def f(**kw):
    print(kw)

f(**A())
$ python kwd.py
{}

it stops working -- probably a side-effect of some optimization.
So if you change your hubDict's base class from dict to object you should 
get the desired behaviour.

Peter



More information about the Python-list mailing list