Christopher said:
If I have the following class:
class MyClass:
def __init__(self):
m_dict = {}
m_dict['one'] = 1
m_dict['two'] = 2
m_dict['three'] = 3
First of all, you need to hold onto a copy of that dict if you want to
be able to do anything with it. You're creating m_dict as a local
variable inside of __init__(), which goes out of scope when __init__()
ends, and is then garbage-collected. To get it to stay around, store it
as an attribute of 'self' --
self.m_dict = {}
self.m_dict['one'] = 1
self.m_dict['two'] = 2
and so on.
Is there anyway to generate automatic accessors to the elements of the dict?
For example, so I could say:
obj = MyClass()
obj.one # returns obj.my_dict['one']
obj.one = 'won' # same as obj.my_dict['one'] = 'won'
If you want to be able to access these items as if they were plain
attributes of your class instance, is there any reason why you're not
just creating them as attributes?
class MyClass:
def __init___(self):
self.one = 1
obj = MyClass()
obj.one # --> 1
obj.one = 'won'
If you really do need to maintain the dict separately, then you can use
__getattr__() and __setattr__() to redirect accesses of nonexistent
attributes into operations on your contained dict, something like this
(untested):
class MyClass(object): # ensure a new-style class
def __init__(self):
self.m_dict = {'one':1, 'two':2, 'three':3}
def __getattr__(self, attr):
value = self.m_dict.get(attr, None)
if value is None:
raise AttributeError(attr)
return value
def __setattr__(self, attr, value):
self.m_dict[attr] = value
I'm using a new-style class to take advantage of improvements in
attribute lookup. For this class, __getattr__()/__setattr__() will only
be called if attr isn't found through the normal attribute resolution
rules.
One problem with the way I'm doing things here is that, if you set a
dict item to a value of None, the object will raise an AttributeError
when trying to access that item. This really ought to use a safer
sentinel value. (Check for a recent thread here in c.l.py about
sentinel values and the use of object() as one.)
It might be possible to use the mechanism you seem to want
(automatically generating individual get/set methods, attaching them to
the instance, creating a new property from the getter/setter), but that
would involve significantly more complexity and magic, and would gain
you very little (if anything).
Jeff Shannon
Technician/Programmer
Credit International