empty classes as c structs?
Steven Bethard
steven.bethard at gmail.com
Mon Feb 7 13:50:53 EST 2005
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
More information about the Python-list
mailing list