Customizing class attribute access in classic classes
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Oct 30 05:23:26 EDT 2011
On Sat, 29 Oct 2011 14:06:12 -0700, Geoff Bache wrote:
> Hi,
>
> I'm wondering if there is any way to customize class attribute access on
> classic classes?
>
> So this works:
>
> class Meta(type):
> def __getattr__(cls, name):
> return "Customized " + name
>
> class A:
> __metaclass__ = Meta
>
> print A.blah
>
> but it turns A into a new-style class.
And why is this a problem?
In any case, metaclasses work for classic classes. Metaclasses go back to
pre-Python 1.5, long before new-style classes and type unification.
http://www.python.org/doc/essays/metaclasses/
You just have to do a lot more work:
class Meta:
def __init__(self, name, bases, namespace):
self.__name__ = name
self.__bases__ = bases
self.__dict__ = namespace
def __str__(self):
return "<Meta instance>"
__repr__ = __str__
def __getattr__(self, name):
return "Customized " + name
def __call__(self):
return self
(The purpose of the __str__ and __repr__ methods is to make it possible
to experiment in the interactive interpreter, without a lot of mysterious
and puzzling "str object is not callable" TypeErrors. Trust me on this.)
And in use:
>>> class Spam:
... __metaclass__ = Meta
... a = 1
...
>>> Spam.b
'Customized b'
But note that using classic classes, there is no equivalent of
__getattribute__ or descriptors, so there is no way to customize access
of an attribute which actually does exist:
>>> Spam.a
1
--
Steven
More information about the Python-list
mailing list