An attempt to use a python-based mini declarative language for formdefinition

Andrew Dalke adalke at mindspring.com
Thu Sep 23 01:52:28 CEST 2004


Carlos Ribeiro wrote:
> I may have made a mistake on my own code, but __setattr__ would not
> work for me; I'm creating my instances through a metaclass, and I'm
> using class attributes for the fields.

I tried too, though not using metaclasses.

 >>> class StoreOrder(dict):
...   def __init__(self, *args, **kwargs):
...     dict.__init__(self, *args, **kwargs)
...     self["_order"] = []
...   def __setitem__(self, k, v):
...     dict.__setitem__(self, k, v)
...     self["_order"].append(k)
...
 >>> x = StoreOrder()
 >>> x["a"] = 9
 >>> x["b"] = 10
 >>> x
{'a': 9, '_order': ['_order', 'a', 'b'], 'b': 10}
 >>> class Form:
...   pass
...
 >>> Form.__dict__ = StoreOrder()
 >>> Form.__dict__
{'_order': ['_order']}
 >>> Form.a = 9
 >>> Form.__dict__
{'a': 9, '_order': ['_order']}
 >>> Form.__dict__["b"] = 10
 >>> Form.b
10
 >>>

What happens is that class assignment sets the
class __dict__ via PyDict_SetItem and not
through the generic mapping interface.  In
essence it does

   dict.__setitem__(self.__dict__, "new class var", val)
instead of
   setitem(self.__dict__, "new class var", val)

Therefore I don't think it's possible to do what
you want.  There's no way to interpose your own
code in class variable assignment.

Here's a way to implement the suggestion of
Thomas Heller's.

import itertools
order_gen = itertools.count().next

class Counted(object):
   def __init__(self):
     self._order = order_gen()

class TextBox(Counted):
   def __init__(self, length, default, password = False):
     Counted.__init__(self)
     self.length = length
     self.default = default
     self.password = password

class Form:
   nickname = TextBox(length=15, default="")
   password = TextBox(length=10, default="swordfish", password=True)

 >>> Form.nickname._order
0
 >>> Form.password._order
1
 >>>

Not as clever as checking the stack trace, but probably
for the better.  :)


				Andrew
				dalke at dalkescientific.com



More information about the Python-list mailing list