kwargs压倒dict子类

时间:2016-10-15 14:15:37

标签: python dictionary kwargs

最小的例子如下:

class sdict(dict):
    class dval:
        def __init__(self, val):
            self.val = val

    def __init__(self, args):
        dictionary = dict(args)
        for k,v in dictionary.items():
            self[k] = v

    def __setitem__(self,key,value):
         try:                   self[key].val = value
         except KeyError:       dict.__setitem__(self,key,self.dval(value))
    def __getitem__(self,key):
         return dict.__getitem__(self,key).val

现在我可以在容器中使用这个类来覆盖赋值内容:

class cont(object):
    def __init___(self):
        self._mydict = sdict(())
    @property
    def mydict(self):
        return self._mydict
    @mydict.setter
    def mydict(self,dict_initializor):
        self._mydict = sdict(dict_initializor)
        return self.mydict

我使用这个,所以我的容器包含一个带有可指向原语的字典(即在python语言中是可变的),但每当我检索该项时,我得到原语本身。在我的情况下浮点数,我乘以,添加等...添加__str __ / __ repr__函数使这在打印时起作用,但出于调试目的,这些都被省略。

这几乎无处不在,除非使用kwargs传递它:

def test(a,b): return a*b
c = cont()
c.mydict = {'a':1,'b':2}
print c.mydict['a']+c.mydict['b'],type(c.mydict['a']+c.mydict['b'])
print test(**c.mydict)

输出:

3 <type 'int'>
Traceback (most recent call last):
  File "D:\kabanus\workspace\py-modules\test.py", line 32, in <module>
    print test(**c.mydict)
  File "D:\kabanus\workspace\py-modules\test.py", line 28, in test
    def test(a,b): return a*b
TypeError: unsupported operand type(s) for *: 'instance' and 'instance'

显然,解包程序不使用__getitem__来为关键字创建值。我还试图覆盖values()和items()但没有成功。接下来,我将我未定义的所有dict方法设置为None,以查看是否有任何调用 - 也没有成功。

底线 - 你怎么得到** kwargs拆包使用__getitem__或其他方法?
这甚至可能吗?

我还想避免在类dval中尽可能地定义mul,add,div等。

1 个答案:

答案 0 :(得分:1)

在这里找到答案,应该有办法让这个更容易找到: Does argument unpacking use iteration or item-getting?

要点: 继承自builtins(dict,list ...)是有问题的,因为python可能完全忽略你的python API(就像它对我做的那样)并使用底层C.这在参数解包中发生。

解决方案:使用可用的抽象。在我的示例中添加:

from UserDict import UserDict

并替换所有&#34; dict&#34;使用UserDict在代码中出现。对于列表和元组,此解决方案应该是正确的。