namespaces module (a.k.a. bunch, struct, generic object, etc.) PEP

Nick Coghlan ncoghlan at iinet.net.au
Sat Feb 12 22:30:07 EST 2005


Yeah, talking to myself again. I had a couple of further thoughts on how to do 
things in an inheritance friendly way. . .

Firstly, for Namespaces handling of special names, I think it would be good to 
make it easy for subclasses to change the sets of names that are handled using 
either Namespace lookup or standard Python lookup.

The simplest way is to make the method that performs the check an instance method.

     class Namespace(object):
         # etc
         def _is_special_name(name):
             return name.startswith("__") and name.endswith("__")

I also think subclasses should be able to affect update() just by defining 
__setattr__ (for example, my LockedView class forgot to deal with update()). So 
I'd replace the calls to self.__dict__.update(other) with calls to 
type(self)._update_dict(self, other):

     class Namespace(object):
         # etc
         def _update_dict(self, other):
             for k in other:
                 setattr(self, k, other[k])

Finally, it might be nice if the get/set/del methods special-cased names with 
dots in them. Consider the following with a normal class:

Py> class C(object): pass
...
Py> c = C()
Py> c.x = C()
Py> setattr(c, "x.y", 1)
Py> getattr(c, "x.y")
1
Py> vars(c.x)
{}
Py> vars(c)
{'x.y': 1, 'x': <__main__.C object at 0x009E0A10>}
Py> c.x.y
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
AttributeError: 'C' object has no attribute 'y'

With a namespace, we can make the dotted access 'just work':

Py> ns = namespaces.Namespace()
Py> ns.x = C()
Py> ns.y = namespaces.Namespace()
Py> setattr(ns, "x.y", C())
Py> setattr(ns, "x.y.z", 1)
Py> setattr(ns, "y.x", C())
Py> setattr(ns, "y.x.z", 2)
Py> vars(ns)
{'y': Namespace(x=<__main__.C object at 0x009EB8D0>), 'x': <__main__.C object at
  0x009EB1F0>}
Py> vars(ns.x)
{'y': <__main__.C object at 0x009EB890>, 'y.z': 1}
Py> vars(ns.y)
{'x': <__main__.C object at 0x009EB8D0>}
Py> vars(ns.y.x)
{'z': 2}

Combined with the update change, it means this code does the right thing:

Py> settings = {
... "x" : 1,
... "y" : namespaces.Namespace(),
... "y.z" : 1,
... "y.x" : "Hi there!",
... }
Py> ns = namespaces.Namespace(settings)
Py> ns
Namespace(x=1, y=Namespace(x='Hi there!', z=1))

Rather than sending it again, I've posted my current code at:
http://members.iinet.net.au/~ncoghlan/public/namespaces.py

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net



More information about the Python-list mailing list