using __setattr__

Jeff Sandys sandysj at asme.org
Wed Aug 30 14:16:33 EDT 2000


Thanks, Mike, it works!  How did you know that?  I spent all day 
reading _Python_Essential_Reference_ and _Learning_Python_ trying 
to figure this out.  All I was getting was self.data == None or 
recursing out of space as __setattr__ tried to __setattr__ ...

Working code and example is below.

The only other mess I don't like about this is that the actual 
code has 26 fields and self.data needs to be initialized with 
26 'slots' to not error out.  Is there a cleaner way (like 26*"") 
to initialize the self.data list?

Mike Fletcher wrote:
> 
> To set a value in the dictionary of an instance where you have a 
> __setattr__ method, use:
>         self.__dict__[ "data" ] = ["     ","        ","       "]
> 
> You can then use simple:
>         self.data
>         self.fields
> statements to reference the attribute.  Note: your __getattr__ 
> handler should explicitly check to see if the key passed is
> "data" and raise an attribute error if it is (because there is 
> no attribute of that name in the dictionary if the __getattr__ 
> hook is called).
> 
<<snip>>
> 
> Hope this helps,
> Mike
> 

class special:
    fields = {'curly':(0,5),
              'moe':(1,8),
              'larry':(2,7)}
    def __init__(self):
        self.__dict__['data'] = ["","",""]
        for item in special.fields.keys():
            (pos, leng) = special.fields[item]
            self.data[pos] = "%-*.*s" % (leng, leng, "")
    def __setattr__(self, item, value):
        if special.fields.has_key(item):
            (pos, leng) = special.fields[item]
            self.data[pos] = "%-*.*s" % (leng, leng, value)
        else:
            raise RuntimeError, "%s is not a field name" % item
    def __getattr__(self, item):
        if special.fields.has_key(item):
            return self.data[special.fields[item][0]]
        else:
            raise RuntimeError, "%s is not a field name" % item
    def record(self):
        return string.join(self.data, "")

>>> x = special()
>>> x.curly = 'tangerine'
>>> x.curly
'tange'
>>> x.moe = 'black'
>>> x.moe
'black   '
>>> x.larry = 'red'
>>> x.larry
'red    '
>>> x.record()
'tangeblack   red    '
>>> y = special()
>>> y.curly = 'blue'
>>> y.curly
'blue '
>>> x.curly
'tange'
>>> x.harry = 'green'
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "/usr/tmp/python-LVcXae", line 15, in __setattr__
RuntimeError: harry is not a field name
>>> x.data
['tange', 'black   ', 'red    ']



More information about the Python-list mailing list