I've long been using a "SmartMap" extended dictionary that naturally allows property access to dictionary content. Create one with a tuple sequence of colName/colValue pairs and you suddenly have a very ORM-like row object. The one I like most delivers a None
for missing keys automatically:
#----------
# Handy tool for objects as "bags of properties"
# by Peter Norvig, enhanced as a subclass of dict() by Philip J. Turmel
# http://norvig.com/python-iaq.html
class SmartMap(dict):
def __repr__(self):
args = []
for (k,v) in self.items():
if isinstance(v, basestring):
args.append('%s=%s' % (k, v))
else:
try:
z = len(v)
args.append('%s=%s' % (k, type(v)))
except:
args.append('%s=%s' % (k, repr(v)))
return 'SmartMap(%s)' % ', '.join(args)
def __str__(self):
args = []
for k,v in self.items():
if isinstance(v, basestring):
args.append('%s=%s' % (k, v))
else:
try:
z = len(v)
args.append('%s=%s' % (k, repr(v)))
except:
args.append('%s=%s' % (k, str(v)))
return 'SmartMap(%s)' % ', '.join(args)
def clone(self):
return type(self)(**self)
def __getattr__(self, attr):
if attr.startswith('__'):
raise AttributeError(attr)
if attr in self:
return self[attr]
return None
def __setattr__(self, attr, val):
if attr.startswith('__'):
super.__setattr__(self, attr, val)
self[attr] = val
If you have a dataset ds
and rowNum
, you can load that row into this model like so:
row = util.SmartMap(zip(ds.columnNames, [ds.getValueAt(rowNum, i) for i in range(ds.columnCount)]))
If you consistently use column names that are valid python identifiers (and you do, right?), everything in the row is now accessible as either row.colName
or row["colName"]
, as needed.
I'd be delighted if the future PyDataset Jython proxy supported this syntax in its row iterator...