> 1) Something that fixes the broken name mangling in the current > system, but still doesn't try to defeat intentional unmangling. > Currently, if you have a class with the same name as one of its > superclasses, the name mangling can fail even its existing purpose of > preventing accidental collisions.
None of what follows offers any protection against malice, but at least "normal" use will be safe. Are there any other idioms where __dict__s are used as dumping grounds for strange objects, in particular superclasses of that object? (For this to work the instance needs a __dict__; fully __slots__'d objects won't be amenable to it) Instead of mangling in the class name: class C: def __init__(self, x): self.__x = x One could mangle in the class itself: class C: def __init__(self, x): self.__dict__[C, 'x'] = x (and retrieve similarly). Now classes with the same name are still regarded as distict. A variation on this is to have a single __dict__ entry for the class, which refers to another dict, so we would have something like def __init__(self, ...): privates = { } self.__dict__[C] = privates # ... def f(self...): privates = self.__dict__[C] # ... and then get or set privates[varName] as needed. (Or possibly use it lazily via setdefault if you have a good idea of the what the defaults should be.) However this means non-strings end up in dir() which may cause things like map str.upper, dir(C())) to fail. Thus instead of C as the key we could use `id(C)`. The only chance for collision I can see in the `id` solution is if an object changes its __class__, then the old class is GC'd, a new one is loaded with the same address as the old, and the __class__ is changed to (a subclass of) this new one. Frankly __class__ reassignment is fairly esoteric, and already has the question of how well the __dict__ from the old type masquerades as a new one. Other scope for collision: if the classes in question are instances of some mad metaclass which defines == to mean something other than identity testing (is). This would only be needed if the objects weren't just used as types, but also something else as well (e.g. collections of all their instances, implemented via weakrefs). Note that this won't quite work for private data in new classes, as their __dict__ is read-only, but I offer the following peculiar hack: class K(object): __dict__ = {} # ... Any normal accesses to K.__dict__ will reach the wrapping dictproxy object, but K.__dict__['__dict__'] is all yours to play with. If you start by assigning __dict__ to locals() in the class initializer, then writes to K.__dict__['__dict__'] will be visible just through K.__dict__. Whether that's desirable or not depends on you. (locals() isn't what you want if you're creating truly dynamic types via type(names, bases, dict), though.) Paranoid/super-open-minded types might wish to replace accesses to __dict__ here with calls to object.__getattribute__(...,'__dict__') in case any subclasses have strange semantics (which may make perfect sense as far as they're concerned, but still potentially be a problem for you having to second-guess them.) Hope this helps John PS Only slightly relevant: when checking out the possibilties for private attrs on types, I ran up against dictproxies. What need did they meet over plain dicts, why are they read-only (at the Python and CPython level), why are they not instantiable directly (though you can always just create a temporary type and steal its __dict__), and why is type's __dict__ is read-only but a class's isn't? I just have down'n'dirty type dict munging to do, and it seems retrograde that it only works with old (and nominally less flexible) classes. -- http://mail.python.org/mailman/listinfo/python-list