how to dynamically generate __name__ for an object?

Fuzzyman fuzzyman at gmail.com
Wed Aug 10 10:48:55 EDT 2011


On Aug 7, 4:06 am, Eric Snow <ericsnowcurren... at 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/



More information about the Python-list mailing list