Zusätzliches Attribut für object

23/06/2010 - 15:27 von Ole Streicher | Report spam
Hallo Gruppe,

ich möchte gerne eine Art Dictionary erstellen, bei dem die Eintràge
sowohl über einen Key als auch als Attribut erreichbar sind.

Gegenwàrtig sieht das so aus:
-8<
class AttributeDict(object):
def __init__(self):
self._dict = dict()

# __getitem__, __setitem__, __delitem__, __contains__, __len__,
# __iter__ werden nach self._dict delegiert

def __getattr__(self, attr):
return self[self._attribute_to_key(attr)]

def __setattr__(self, attr, value):
if attr.startswith('_'):
super(object, self).__setattr__(attr, value)
else:
self[self._attribute_to_key(attr)] = value

def __delattr__(self, attr):
del self[self._attribute_to_key(attr)]

def __dir__(self):
return [ self._key_to_attribute(key) for key in self._dict.keys() ]

def _attribute_to_key(self, attr):
return attr

def _key_to_attribute(self, key):
return key
-8<

Das problem ist jetzt, dass das __init__ schon fehlschàgt, und zwar mit
der Bemerkung

attributedict.py in __setattr__(self, attr, value)
34 def __setattr__(self, attr, value):
35 if attr.startswith('_'):

36 super(object, self).__setattr__(attr, value)


37 else:
38 self[self._attribute_to_key(attr)] = value

AttributeError: 'super' object has no attribute '_dict'

was ja nicht ganz unverstàndlich ist. Aber, wie kann ich es erreichen,
dass ich ein zusàtzliches Objekt "_dict" erzeuge, und ist das gezeigte
Vorgehen überhaupt sinnvoll bzw. wo gibt es Verbesserungsmöglichkeiten?

Viele Grüße

Ole
 

Lesen sie die antworten

#1 Peter Otten
23/06/2010 - 16:06 | Warnen spam
Ole Streicher wrote:

Hallo Gruppe,

ich möchte gerne eine Art Dictionary erstellen, bei dem die Eintràge
sowohl über einen Key als auch als Attribut erreichbar sind.

Gegenwàrtig sieht das so aus:



-8<
class AttributeDict(object):
def __init__(self):
self._dict = dict()

# __getitem__, __setitem__, __delitem__, __contains__, __len__,
# __iter__ werden nach self._dict delegiert

def __getattr__(self, attr):
return self[self._attribute_to_key(attr)]

def __setattr__(self, attr, value):
if attr.startswith('_'):
super(object, self).__setattr__(attr, value)



super(AttributeDict, self).__setattr__(attr, value)

Faustregel: erstes Argument von super() ist immer die Klasse, die du gerade
implementierst.

else:
self[self._attribute_to_key(attr)] = value

def __delattr__(self, attr):
del self[self._attribute_to_key(attr)]

def __dir__(self):
return [ self._key_to_attribute(key) for key in self._dict.keys()
]

def _attribute_to_key(self, attr):
return attr

def _key_to_attribute(self, key):
return key



-8<

Das problem ist jetzt, dass das __init__ schon fehlschàgt, und zwar mit
der Bemerkung

attributedict.py in __setattr__(self, attr, value)
34 def __setattr__(self, attr, value):
35 if attr.startswith('_'):
> 36 super(object, self).__setattr__(attr, value)
37 else:
38 self[self._attribute_to_key(attr)] = value

AttributeError: 'super' object has no attribute '_dict'

was ja nicht ganz unverstàndlich ist. Aber, wie kann ich es erreichen,
dass ich ein zusàtzliches Objekt "_dict" erzeuge, und ist das gezeigte
Vorgehen überhaupt sinnvoll bzw. wo gibt es Verbesserungsmöglichkeiten?



Wenn du damit leben kannst, dass nur str-Keys erlaubt sind, geht auch

class A(object):






... def __getitem__(self, key): return getattr(self, key)
... def __setitem__(self, key, value): setattr(self, key, value)
...
a = A()
a["x"] = 42
a.x






42
a[1] = "foo"






Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __setitem__
TypeError: attribute name must be string, not 'int'
a[""] = "bar"
a.__dict__[""]






'bar'

Peter

Ähnliche fragen