I’m writing a C binding, and the C structure that I’m wrapping has some string-indexed property values.
I’d like to expose these as a dict in python.
So far, I’ve got a function get_properties, which returns all the object’s properties as a single dict. I wrapped this using the property function in the class definition, so that I can access it as a class attribute:
(in class definition)
class MyClass:
def get_properties(self):
...
properties = property(get_properties)
(example)
>>> print myobj.properties
{'test': 5, 'test2': 'string'}
Now, I’d like to handle setting them in a dict-like way. I have a wrapper function for the C function called set_property, which takes a string key and a value of several types.
I tried using set_properties from my class property:
class MyClass:
def get_properties(self):
...
def set_property(self, key, value):
...
def set_properties(self, props):
[self.set_property(k, props[k]) for k in props]
properties = property(get_properties, set_properties)
This works like this following:
>>> myobj.properties = {"test3": 6}
>>> print myobj.properties
{'test': 5, 'test2': 'string', 'test3': 6}
However, as you can see it’s not entirely the expected behaviour. What I’d prefer is something like:
>>> myobj.properties['test3'] = 6
I tried adding a definition for __setitem__ to properties:
class MyClass:
...
properties = property(get_properties)
properties.__setitem__ = set_property
But this got me,
AttributeError: 'property' object has no attribute '__setitem__'
I tried to make property a dict and simply override __setitem__ and __getitem__ but it wouldn’t have it.
Any idea what the correct way to do this is? Can I make a class property behave like a dictionary?
Thanks.
Okay, Mike’s answer gave me the idea to solve this by returning from the property’s getter with an extended dict class, in which I override
__setitem__based on the context:Seems to work as I want.