Nick Coghlan wrote:
Steven Bethard wrote:
It was because these seem like two separate cases that I wanted two different functions for them (__init__ and, say, dictview)...
I see this, but I think it weakens the case for a single implementation, given that each implementation is essentially one method.
Do you mean there should be a separate Namespace and Bunch class? Or do you mean that an implementation with only a single method is less useful?
If the former, then you either have to repeat the methods __repr__, __eq__ and update for both Namespace and Bunch, or one of Namespace and Bunch can't be __repr__'d, __eq__'d or updated.
If the latter (setting aside the fact that the implementation provides 4 methods, not 1), I would argue that even if an implementation is only one method, if enough users are currently writing their own version, adding such an implementation to the stdlib is still a net benefit.
I think Michael's implementation also fell into a trap whereby 'E' couldn't be used as an attribute name. The version below tries to avoid this (using magic-style naming for the other args in the methods which accept keyword dictionaries).
You're right - I hadn't considered that. In case it wasn't obvious, I was matching the argspec of dict. Your solution avoids the problem.
Another way to avoid the problem is to use *args, like the current Bunch implementation does:
def update(*args, **kwargs): """bunch.update([bunch|dict|seq,] **kwargs) -> None
Updates the Bunch object's attributes from (if provided) either another Bunch object's attributes, a dictionary, or a sequence of (name, value) pairs, then from the name=value pairs in the keyword argument list. """ if not 1 <= len(args) <= 2: raise TypeError('expected 1 or 2 arguments, got %i' % len(args)) self = args[0] if len(args) == 2: other = args[1] if isinstance(other, Bunch): other = other.__dict__ try: self.__dict__.update(other) except (TypeError, ValueError): raise TypeError('cannot update Bunch with %s' % type(other).__name__) self.__dict__.update(kwargs)
This even allows you to use the keywords __self__ and __orig__ if you're sick enough to want to. It's slightly more work, but I prefer it because it's more general.
To limit the special casing in update, I've switched to only using __dict__ for the specific case of instances of namespace
That seems a pity to me.
Is it that much worse to require the following code:
Namespace.update(namespace, obj.__dict__)
or:
namespace.udpate(obj.__dict__)
if you really want to update a Namespace object with the attributes of a non-Namespace object?
For that matter, do you have a use-case for where this would be useful? I definitely see the view-of-a-dict example, but I don't see the view-of-an-object example since an object already has dotted-attribute style access...
This is to allow easy copying of an existing namespace -
Can't this be spelled namespace(somenamespace).__copy__()?
I'd prefer to be consistent with dict, list, set, deque, etc. all of which use their constructor for copying.
We could use __add__, instead for combining namespaces
I don't think this is a good idea. For the same reasons that dicts don't have an __add__ (how should attributes with different values be combined?), I don't think Bunch/Namespace should have an __add__.
Steve -- http://mail.python.org/mailman/listinfo/python-list