Using metaclasses to make super more beatiful
Michele Simionato
mis6 at pitt.edu
Fri Jun 6 11:00:21 EDT 2003
Gerrit Holl <gerrit at nl.linux.org> wrote in message news:<mailman.1054831871.3625.python-list at python.org>...
<snip message on autosuper>
You may want to google for the thread "help on autosuper" date February 3,
2003. At the time I found that the autosuper metaclass was conflicting
with pydoc:
# try this under Python 2.2
class autosuper(type): #Guido's metaclass
def __init__(cls, name, bases, dic):
super(autosuper, cls).__init__(name, bases, dic)
setattr(cls,"_%s__super" % name, super(cls))
class C(object): #a simple class
__metaclass__=autosuper
help(C) # error because super objects have not __name__
For this reason I abandoned the autosuper approach. However, I have
checked today with Python 2.3 and now it works! The reason is that now
private attributes are no more retrieved by pydoc, therefore the
inconsistency is hidden under the hood. However, it is still there and
if you do
# try this under Python 2.2-2.3
class C(object): pass
C.sup=super(C)
help(C)
you will get
Traceback (most recent call last):
File "pro.py", line 15, in ?
help(C)
File "/usr/local/lib/python2.3/site.py", line 293, in __call__
return pydoc.help(*args, **kwds)
File "/usr/local/lib/python2.3/pydoc.py", line 1539, in __call__
self.help(request)
File "/usr/local/lib/python2.3/pydoc.py", line 1575, in help
else: doc(request, 'Help on %s:')
File "/usr/local/lib/python2.3/pydoc.py", line 1368, in doc
pager(title % desc + '\n\n' + text.document(object, name))
File "/usr/local/lib/python2.3/pydoc.py", line 279, in document
if inspect.isclass(object): return self.docclass(*args)
File "/usr/local/lib/python2.3/pydoc.py", line 1122, in docclass
lambda t: t[1] == 'method')
File "/usr/local/lib/python2.3/pydoc.py", line 1057, in spill
name, mod, object))
File "/usr/local/lib/python2.3/pydoc.py", line 280, in document
if inspect.isroutine(object): return self.docroutine(*args)
File "/usr/local/lib/python2.3/pydoc.py", line 1145, in docroutine
realname = object.__name__
AttributeError: 'super' object has no attribute '__name__'
Another reason to use private attributes ;) There is a simple fix, anyway:
class Super(super):
def __init__(self,C,S=None):
super(Super,self).__init__(C,S)
self.__name__="Super(%s)" % C.__name__
To you and to other explorers of the wonders of super, I say "DON'T
USE 2.2!". There were many subtle bugs now mostly solved in 2.3 (except
the one with pydoc, AFAIK).
Cheers,
Michele
More information about the Python-list
mailing list