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

Kresimir Kumericki kkumer at calculon.phy.hr
Tue Jun 8 05:01:59 EDT 2010


Peter Otten <__peter__ at web.de> wrote:
> 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

-- 
Kresimir Kumericki                            http://www.phy.hr/~kkumer/



More information about the Python-list mailing list