Michael Spencer wrote:
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

Reply via email to