Steven Bethard wrote:>>> ns = Namespace(eggs=1) >>> Namespace.update(ns, [('spam', 2)], ham=3) >>> ns Namespace(eggs=1, ham=3, spam=2)
Note that update should be used through the class, not through the instances, to avoid the confusion that might arise if an 'update' attribute added to a Namespace instance hid the update method.
I'd like to see the PEP text itself encourage the more inheritance friendly style used in the __init__ method:
type(ns).update(ns, [('spam', 2)], ham=3)
Where in the PEP do you think this belongs? Or did you mean you wanted it in the docstrings of the Namespace functions?
Note that support for the various mapping methods, e.g. __(get|set|del)item__, __len__, __iter__, __contains__, items, keys, values, etc. was intentionally omitted as these methods did not seem to be necessary for the core uses of an attribute-value mapping. If such methods are truly necessary for a given use case, this may suggest that a dict object is a more appropriate type for that use.
The 'vars' builtin also makes it trivial to use dictionary style operations to manipulate the contents of a Namespace.
Right, I had meant to mention that. Thanks!
Should namespace chaining be supported? One suggestion would add a NamespaceChain object to the module::
This does have the advantage of keeping the basic namespace simple. However, it may also be worth having native chaining support in Namespace:
I think I prefer the separate NamespaceChain object because it allows you to chain namespaces other than just Namespace objects -- any object that supports getattr is okay. If chaining is builtin, all namespaces (except the last one?) have to be Namespace objects...
class NamespaceChain(object): """NamespaceChain(*objects) -> new attribute lookup chain
The new NamespaceChain object's attributes are defined by the attributes of the provided objects. When an attribute is requested, the sequence is searched sequentially for an object with such an attribute. The first such attribute found is returned, or an AttributeError is raised if none is found.
Note that this chaining is only provided for getattr and delattr operations -- setattr operations must be applied explicitly to the appropriate objects.
Hmm, I'm not so sure about this. I think that the right model is the way that a class instance is currently chained with its class.
That is, assume we have the following: c = cls() ns = Namespace(vars(c), vars(cls)) # Using modified NS above nc = NamespaceChain(Namespace(vars(c)), Namespace(vars(cls)))
I would expect modification of attributes on ns or nc to behave similarly to modification of attributes on c - attribute retrieval follows the chain, but attribute modification (set/del) always operates on the first namespace in the chain.
Yeah, that makes sense. I hadn't quite wrapped my head around what setattr _aught_ to do in these cases, so I wasn't willing to commit to anything yet. ;) I'll update NamespaceChain to work like classes do...
Steve -- http://mail.python.org/mailman/listinfo/python-list