"indexed properties"...
David C. Ullrich
dullrich at sprynet.com
Wed May 14 17:15:41 EDT 2008
Having a hard time phrasing this in the form
of a question...
The other day I saw a thread where someone asked
about overrideable properties and nobody offered
the advice that properties are Bad. So maybe we've
got over that. I suppose properties could have
Bad consequences if a user doesn't know they exist
and think that a certain property of an object is
just an ordinary attribute. But that applies to
almost any aspect of any language.
If a person comes from, say, Object Pascal (Delphi)
then properties are hard to live without. The
other day I decided I wanted what OP calls an
"indexed property" or "array property". Couldn't
figure out how to make a _property_ behave that way.
So I read a little bit about descriptors, and a
few minutes later I had an indexedproperty thing
that works just like property, except it gives
an indexed property! This is just too cool.
Why? For example, a Matrix should have a row[n]
property allowing things like
m.row[0] = m.row[1] + m.row[2]
Ok, you could do _that_ by just making row
an ordinary list of Row objects. But then
you'd have to say
m.row[0] = Row([1,2,3])
where I want to be able to say
m.row[0] = [1,2,3]
and have the Row created automatically.
_Also_ with these indexed properties my Matrix
can have m.row[j] and m.col[k] that look exactly
the same to a client - we don't want to store a
list of rows internally and also store the same
data in a list of columns. Too cool.
Hmm, none of that's a valid excuse for a post here.
Um, right, here we go: Anyone see problems or
possible improvements with the implementation
of indexedproperty below?
"""indexed.py: "indexedproperty" works more or less
like "property" except it gives what in Object Pascal
would be an "indexed property". See the
__name__="__main__" section below for a demo
"""
class WriteOnlyIP(Exception):
def __str__(self):
return """
indexed property is write-only
"""
class ReadOnlyIP(Exception):
def __str__(self):
return """
indexed property is read-only
"""
class indexedproperty(object):
def __init__(self, getitem=None, setitem=None):
self.getitem = getitem
self.setitem = setitem
def __get__(self, obj, owner):
self.obj = obj
return self
def __getitem__(self, index):
if self.getitem:
return self.getitem(self.obj, index)
else:
raise WriteOnlyIP
def __setitem__(self, index, value):
if self.setitem:
self.setitem(self.obj, index, value)
else:
raise ReadOnlyIP
if __name__ == "__main__":
class AClass(object):
def __init__(self):
self.cells = [[0,0], [0,0]]
def SetCell(self, (row, col), value):
self.cells[row][col] = value
def GetCell(self, (row, col)):
return self.cells[row][col]
cell = indexedproperty(GetCell, SetCell)
C = AClass()
for row in range(2):
for col in range(2):
C.cell[row, col] = "row: %s, col: %s" % (row, col)
for row in range(2):
for col in range(2):
print C.cell[row, col]
C.cell[0,0], C.cell[1,1] = C.cell[1,1], C.cell[0,0]
print "After C.cell[0,0], C.cell[1,1] = C.cell[1,1], C.cell[0,0]:"
for row in range(2):
for col in range(2):
print C.cell[row, col]
--
David C. Ullrich
More information about the Python-list
mailing list