Newbie question about class operator overloading

Steven Bethard steven.bethard at gmail.com
Tue Feb 15 17:21:52 EST 2005


Rory Campbell-Lange wrote:
> Hi. I'm just starting to use python.
> 
> I am anxious about how best to set and access items one level down in a
> data structure if I am using __setitem__ and __getitem__.
> 
> At the moment I can do
> 
> for a data structure Data:
> 
>     object.Data = { 'one' : [1, 2, {}, 4],
>                     'two' : [5, 6, {}, 8]}

What is the goal of this data structure?  I have a feeling this needs to 
be refactored...

> However, if I wish to access object.Data['one'][0] for instance, I am
> using the following:
> 
> object['three'] = [0, 'val0'] # set
> x =  object['three'][0]       # get

Seems like you'd do much better with names for the items rather than an 
index.  Maybe something like:

py> class Record(object):
...     def __init__(self, foo, bar, dict, baz):
...         self.foo = foo
...         self.bar = bar
...         self.dict = dict
...         self.baz = baz
...     def __repr__(self):
...         return 'Record(%r, %r, %r, %r)' % ( 

...             self.foo, self.bar, self.dict, self.baz)
...
py> data = dict(one=Record(1, 2, {}, 4),
...             two=Record(5, 6, {}, 8))
py> data
{'two': Record(5, 6, {}, 8), 'one': Record(1, 2, {}, 4)}
py> data['one'].foo = 'val0'
py> data
{'two': Record(5, 6, {}, 8), 'one': Record('val0', 2, {}, 4)}
py> data['one'].foo
'val0'

> Is this advisable? I'm worried the syntax is very odd.

Yes it is odd.  If you want to be more consistent with other Python 
syntax, but you don't want to use a Record, check for keys as tuples:

py> class C(object):
...     def __init__(self):
...         self.data = {}
...     def __setitem__(self, x, value):
...         try:
...             name, index = x
...             self.data.setdefault(name, {})[index] = value
...         except ValueError:
...             self.data[x] = value
...     def __getitem__(self, x):
...         try:
...             name, index = x
...             return self.data[name][index]
...         except ValueError:
...             return self.data[x]
...
py> c = C()
py> c.data
{}
py> c['one', 0] = 1
py> c['one', 3] = 4
py> c['two', 1] = 6
py> c['two', 2] = {}
py> c.data
{'two': {1: 6, 2: {}}, 'one': {0: 1, 3: 4}}
py>

As you can see, Python has builin syntax support to allow tuples to be 
used as dict keys.  (The parentheses can be omitted.)

Still, I think the class-based solution is much better than the 
__getitem__/__setitem__ one.

STeVe



More information about the Python-list mailing list