empty classes as c structs?

Michael Spencer mahs at telcopartners.com
Mon Feb 7 20:33:29 EST 2005


Steven Bethard wrote:

> 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?

The former.
> 
> 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.

I see no problem in repeating the methods, or inheriting the implementation. 
However, if namespace and bunch are actually different concepts (one with 
reference semantics, the other with copy), then __repr__ at least would need to 
be specialized, to highlight the difference.

So, on balance, if copy semantics are important to bunch uses, and references 
for namespace (though Nick changed his mind on this, and I don't yet know why) I 
think they would be better as two small implementations.  I remain unsure about 
why you need or want copying, aside from matching the behavior of the builtins.

> 
> 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.

Yes, I agree with this: I was not picking on the class size ;-)

...
> 
> 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

Sure - nice trick to avoid shadowing self too

...
> 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?

No problem at all - just a question of what the class is optimized for, and 
making the interface as convenient as possible, given the use case.  I agree 
that for straight attribute access to a dictionary, your update interface is 
clearly superior.

> 
> 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...


Yes, I have various cases in mind relating to argument-passing, dispatching, 
interface-checking and class composition.  Here the class becomes useful if it 
grows some namespace-specific semantics.

For example, I could write something like:
namespace(obj1) >= namespace(obj2) to mean obj1 has at least the attributes of obj2

implemented like:

def __ge__(self, other):
     for attrname in other.__dict__.keys():
         if not attrname in self.__dict__:
             return False
     return True

I realize that interfaces may be addressed formally by a current PEP, but, even 
if they are, this "cheap and cheerful" approach appeals to me for duck-typing.


However, as I think more about this, I realize that I am stretching your concept 
past its breaking point, and that whatever the merits of this approach, it's not 
helping you with bunch.  Thanks for knocking the ideas around with me.

Cheers

Michael




More information about the Python-list mailing list