<top_posting><br>I like this version very much. I'm ready to put this into practice to see how it<br>works in practice.<br><br>A minor point: I envision this to be used in a context where all key values are <br>strings (legal attribute identifiers). But constructing an AttrClass from a dict <br>
or setting values directly with the dict syntax can allow any valid item as a<br>dict key -- specifically numbers, tuples, etc. If the user of this class chooses<br>to do this, a number of the items become inaccessible to the attribute syntax.<br>
In my case, I think this won't be a problem since I anticipate that values will<br>always be set by the attribute syntax, but it might be an issue for other uses.<br></top_posting><br><br><div class="gmail_quote">
On Fri, Sep 4, 2009 at 6:01 AM, Jan Kaliszewski <span dir="ltr"><<a href="mailto:zuo@chopin.edu.pl">zuo@chopin.edu.pl</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
[originally from <a href="mailto:python-list@python.org" target="_blank">python-list@python.org</a>,<br>
 crossposted to <a href="mailto:python-ideas@python.org" target="_blank">python-ideas@python.org</a>]
<br></blockquote><div>[snip] </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
  class AttrDict(dict):  # (or maybe from OrderedDict)<br>
      "It's only a model. (Shhh!)"<br>
<br>
      def __getattr__(self, name):<br>
          if name.startswith('_'):<br>
              raise AttributeError("AttrDict's key can't "<br>
                                   "start with underscore")<br>
          else:<br>
              return self[name]<br>
<br>
      def __setattr__(self, name, value):<br>
          self[name] = value<br>
<br>
      def __delattr__(self, name):<br>
          del self[name]<br>
<br>
      def __repr__(self):<br>
          return '{0}({1})'.format(self.__class__.__name__,<br>
                                     dict.__repr__(self))<br>
      def __str__(self):<br>
          return self._as_str()<br>
<br>
      def _gen_format(self, indwidth, indstate):<br>
          indst = indstate * ' '<br>
          ind = (indstate + indwidth) * ' '<br>
          yield ('\n' + indst + '{' if indstate else '{')<br>
          for key, val in self.items():<br>
              valstr = (str(val) if not isinstance(val, AttrDict)<br>
                        else val._as_str(indwidth, indstate + indwidth))<br>
              yield '{ind}{key}: {valstr}'.format(ind=ind, key=key,<br>
                                                  valstr=valstr)<br>
          yield indst + '}'<br>
<br>
      def _as_str(self, indwidth=4, indstate=0):<br>
          return '\n'.join(self._gen_format(indwidth, indstate))<br>
<br>
      def _as_dict(self):<br>
          return dict.copy(self)<br>
<br>
<br>
  # Test code:<br>
  if __name__ == '__main__':<br>
      struct = AttrDict()<br>
      struct.first = 1<br>
      struct.second = 2.0<br>
      struct.third = '3rd'<br>
      struct.fourth = [4]<br>
      print(struct)<br>
      # output:<br>
      # {<br>
      #     'second': 2.0<br>
      #     'fourth': [4]<br>
      #     'third': '3rd'<br>
      #     'first': 1<br>
      # }<br>
<br>
      del struct.fourth<br>
<br>
      print(repr(struct))<br>
      # output:<br>
      # AttrDict({'second': 2.0, 'third': '3rd', 'first': 1})<br>
<br>
      print(struct.first)  # (static access)<br>
      # output:<br>
      # 1<br>
<br>
      for x in ('first', 'second', 'third'):<br>
          print(struct[x])  # (dynamic access)<br>
      # output:<br>
      # 1<br>
      # 2.0<br>
      # 3rd<br>
<br>
      struct.sub = AttrDict(a=1, b=2, c=89)<br>
      print(struct._as_dict())<br>
      # output:<br>
      # {'second': 2.0, 'sub': AttrDict({'a': 1, 'c': 89, 'b': 2}),\<br>
      #                                  'third': '3rd', 'first': 1}<br>
<br>
      print(struct._as_str(8))<br>
      # output:<br>
      # {<br>
      #         second: 2.0<br>
      #         sub:<br>
      #         {<br>
      #                 a: 1<br>
      #                 c: 89<br>
      #                 b: 2<br>
      #         }<br>
      #         third: 3rd<br>
      #         first: 1<br>
      # }<br>
<br>
<br>
What do you think about it?<br>
<br>
Cheers,<br>
*j<br><font color="#888888">
<br>
-- <br>
Jan Kaliszewski (zuo) <<a href="mailto:zuo@chopin.edu.pl" target="_blank">zuo@chopin.edu.pl</a>></font><div><div></div><div class="h5"><br>
-- <br>
<a href="http://mail.python.org/mailman/listinfo/python-list" target="_blank">http://mail.python.org/mailman/listinfo/python-list</a><br>
</div></div></blockquote></div><br>