On Aug 7, 4:06 am, Eric Snow <ericsnowcurren...@gmail.com> wrote: > Thought I knew how to provide a dynamic __name__ on instances of a > class. My first try was to use a non-data descriptor: > > # module base.py > > class _NameProxy(object): > def __init__(self, oldname): > self.oldname = oldname > def __get__(self, obj, cls): > if obj is None: > return self.oldname > if "__name__" not in obj.__dict__: > return str(obj.__context__) > return obj.__name__ > > class _BaseMeta(type): > def __init__(cls, name, bases, namespace): > cls.__name__ = _NameProxy(name) > > class Base(object): > __metaclass__ = _BaseMeta > > $ python _base.py > Traceback (most recent call last): > ... > File "/usr/local/lib/python2.4/site-packages/base.py", line xx, in __init__ > cls.__name__ = _NameProxy(name) > TypeError: Error when calling the metaclass bases > can only assign string to Base.__name__, not '_NameProxy' > > Needless to say I was surprised. After looking in typeobject.c, I > believe that __name__ must be a string where classes are concerned[1]. > So if I want all my instances to have a __name__ attribute, and for > it to be dynamically provided if it isn't set on the instance, what > are my options? Or maybe I did something wrong and it should work as > I expected? >
__name__ can be a descriptor, so you just need to write a descriptor that can be fetched from classes as well as instances. Here's an example with a property (instance only): >>> class Foo(object): ... @property ... def __name__(self): ... return 'bar' ... >>> Foo().__name__ 'bar' Michael -- http://voidspace.org.uk/ -- http://mail.python.org/mailman/listinfo/python-list