possible attribute-oriented class
Jan Kaliszewski
zuo at chopin.edu.pl
Fri Sep 4 09:01:02 EDT 2009
[originally from python-list at python.org,
crossposted to python-ideas at python.org]
04-09-2009 o 00:46:01 Ken Newton <krnewton at gmail.com> wrote:
> I have created the following class definition with the idea of making
> a clean syntax for non-programmers to created structured data within a
> python environment.
>
> I would appreciate comments on this code. First, is something like
> this already done? Second, are there reasons for not doing this? If
> this seems OK, how could I clean up the string conversion to have
> indented format.
>
> The expected use would have all items in the structure be simple
> python types or AttrClass types. Code written in python could walk the
> structure in a simple way to locate any desired values. Code in a
> C/C++ extension should also be able to walk the structure to use any
> value in the structure.
>
> class AttrClass(object):
> """AttrClass lets you freely add attributes in nested manner"""
>
> def __init__(self):
> pass
> def __setitem__(self, key, value):
> return self.__dict__.__setitem__(key, value)
> def __repr__(self):
> return "%s(%s)" % (self.__class__.__name__,
> self.__dict__.__repr__())
> def __str__(self):
> ll = ['{']
> for k,v in self.__dict__.iteritems():
> ll.append("%s : %s" % (k, str(v)))
> return '\n'.join(ll) + '}'
[snip]
I find the idea interesting and close to my own needs in many
situations, if I could alter it a bit.
Of course, we always can use an empty class ('class MyStruct: pass')
or simply use a dict... But both methods are inconvinient in some
ways.
In the case of dict we are convicted -- even when we need static
access -- to mapping notation (obj['member']) which is less
convenient and (what's more important) more error-prone than
attribute dot-notation.
In the case of empty class/object we can use convenient attr
dot-notation but dynamic access is less natural...
IMHO there could be -- in collections module or even as a built-in
factory function -- something (somehow) similar to namedtuple, but
mutable and more dict-like. I'am less focused on nesting such
structures, and more on making it a namespace-like objects with
convenience-and-today-usage features. Please consider the code:
class AttrDict(dict): # (or maybe from OrderedDict)
"It's only a model. (Shhh!)"
def __getattr__(self, name):
if name.startswith('_'):
raise AttributeError("AttrDict's key can't "
"start with underscore")
else:
return self[name]
def __setattr__(self, name, value):
self[name] = value
def __delattr__(self, name):
del self[name]
def __repr__(self):
return '{0}({1})'.format(self.__class__.__name__,
dict.__repr__(self))
def __str__(self):
return self._as_str()
def _gen_format(self, indwidth, indstate):
indst = indstate * ' '
ind = (indstate + indwidth) * ' '
yield ('\n' + indst + '{' if indstate else '{')
for key, val in self.items():
valstr = (str(val) if not isinstance(val, AttrDict)
else val._as_str(indwidth, indstate + indwidth))
yield '{ind}{key}: {valstr}'.format(ind=ind, key=key,
valstr=valstr)
yield indst + '}'
def _as_str(self, indwidth=4, indstate=0):
return '\n'.join(self._gen_format(indwidth, indstate))
def _as_dict(self):
return dict.copy(self)
# Test code:
if __name__ == '__main__':
struct = AttrDict()
struct.first = 1
struct.second = 2.0
struct.third = '3rd'
struct.fourth = [4]
print(struct)
# output:
# {
# 'second': 2.0
# 'fourth': [4]
# 'third': '3rd'
# 'first': 1
# }
del struct.fourth
print(repr(struct))
# output:
# AttrDict({'second': 2.0, 'third': '3rd', 'first': 1})
print(struct.first) # (static access)
# output:
# 1
for x in ('first', 'second', 'third'):
print(struct[x]) # (dynamic access)
# output:
# 1
# 2.0
# 3rd
struct.sub = AttrDict(a=1, b=2, c=89)
print(struct._as_dict())
# output:
# {'second': 2.0, 'sub': AttrDict({'a': 1, 'c': 89, 'b': 2}),\
# 'third': '3rd', 'first': 1}
print(struct._as_str(8))
# output:
# {
# second: 2.0
# sub:
# {
# a: 1
# c: 89
# b: 2
# }
# third: 3rd
# first: 1
# }
What do you think about it?
Cheers,
*j
--
Jan Kaliszewski (zuo) <zuo at chopin.edu.pl>
More information about the Python-list
mailing list