On 8/10/2007 4:14 AM, Steven Bethard wrote: > Licheng Fang wrote: >> Python is supposed to be readable, but after programming in Python for >> a while I find my Python programs can be more obfuscated than their C/C >> ++ counterparts sometimes. Part of the reason is that with >> heterogeneous lists/tuples at hand, I tend to stuff many things into >> the list and *assume* a structure of the list or tuple, instead of >> declaring them explicitly as one will do with C structs. So, what used >> to be >> >> struct nameval { >> char * name; >> int val; >> } a; >> >> a.name = ... >> a.val = ... >> >> becomes cryptic >> >> a[0] = ... >> a[1] = ... >> >> Python Tutorial says an empty class can be used to do this. But if >> namespaces are implemented as dicts, wouldn't it incur much overhead >> if one defines empty classes as such for some very frequently used >> data structures of the program? >> >> Any elegant solutions? > > You can use __slots__ to make objects consume less memory and have > slightly better attribute-access performance. Classes for objects that > need such performance tweaks should start like:: > > class A(object): > __slots__ = 'name', 'val' > > The recipe below fills in the obvious __init__ method for such classes > so that the above is pretty much all you need to write: > > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/502237 > >
If not needing/wanting __slots__, something simpler (no metaclasses!) like the following helps the legibility/utility: <file record.py> class BaseRecord(object): def __init__(self, **kwargs): for k, v in kwargs.iteritems(): setattr(self, k, v) def dump(self, text=''): print '== dumping %s instance: %s' % (self.__class__.__name__, text) for k, v in sorted(self.__dict__.iteritems()): print ' %s: %r' % (k, v) </file record.py> Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> from record import BaseRecord >>> class A(BaseRecord): ... pass ... >>> class B(BaseRecord): ... pass ... >>> a1 = A(foo=1, bar='rab', zot=(1, 2)) >>> a2 = A(foo=2, bar='xxx', zot=(42, 666)) >>> a1.dump() == dumping A instance: bar: 'rab' foo: 1 zot: (1, 2) >>> a2.dump('more of the same') == dumping A instance: more of the same bar: 'xxx' foo: 2 zot: (42, 666) >>> a1.ugh = 'poked in' >>> a1.dump('after poking') == dumping A instance: after poking bar: 'rab' foo: 1 ugh: 'poked in' zot: (1, 2) >>> b1 = B() >>> b1.dump() == dumping B instance: >>> b1.esrever = 'esrever'[::-1] >>> b1.dump() == dumping B instance: esrever: 'reverse' >>> HTH, John -- http://mail.python.org/mailman/listinfo/python-list