2016-10-15 3 views
2

Ein minimales Beispiel ist wie folgt:kwargs zwingende dict Unterklasse

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 

Jetzt habe ich diese Klasse in einem Container Zuordnung Sachen außer Kraft setzen kann:

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 

Ich benutze dies so mein Behälter hält eine Wörterbuch mit Pointable-Primitiven (dh änderbar in Python-Sprache), aber immer wenn ich das Element abrufe, bekomme ich das Primitive selbst. In meinem Fall floats, die ich multipliziere, füge etc ... hinzu. Das Hinzufügen von __str __/__ repr__ -Funktionen funktioniert beim Drucken dieser, aber zu Debugging-Zwecken werden diese weggelassen.

Dies funktioniert gut fast überall, außer wenn diese zusammen mit kwargs vorbei:

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) 

Ausgang:

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' 

Offensichtlich ist das Auspacken Verfahren verwendet nicht __getitem__ zu schaffen Werte für die Schlüsselwörter. Ich habe auch versucht, Werte() und Items() ohne Erfolg zu überschreiben. Als nächstes setze ich alle von mir nicht definierten Dict-Methoden auf None, um zu sehen, ob irgendwelche aufgerufen werden - auch kein Erfolg.

Fazit - wie erhalten Sie ** Kwargs entpacken, um __getitem__ oder eine andere Methode zu verwenden?
Ist das überhaupt möglich?

Ich möchte auch vermeiden, mul, add, div und so weiter zu definieren, wenn möglich in der Klasse dval.

+0

Gibt es einen Grund, warum Sie 'dval' verwenden möchten, anstatt die Werte direkt als Ganzzahlen zu setzen? –

+0

Yup - Ich möchte nur Zeiger auf diese Elemente haben. Ich habe nicht den vollständigen Code gepostet, den ich darauf besteht, ist nicht relevant, aber es gibt eine andere innere Klasse namens dview, die eine val propery hat, die den pointed auf integer zurückgibt und set nicht erlaubt. – kabanus

Antwort

1

hier die Antwort gefunden, und soll es eine Möglichkeit, dies einfacher zu machen zu finden: Does argument unpacking use iteration or item-getting?

Zusammenfassung: von builtins Vererben (dict, Liste ...) ist problematisch, da Python Ihren Python ignorieren API vollständig (wie es für mich getan hat) und verwenden Sie das zugrunde liegende C. Dies geschieht beim Entpacken von Argumenten.

Lösung: Verwenden Sie die verfügbaren Abstraktionen. In meinem Beispiel hinzufügen:

from UserDict import UserDict 

und ersetzen Sie alle "dict" Vorkommen im Code mit UserDict. Diese Lösung sollte für Listen und Tupel gelten.