Refine docs for super() noting that sibling classes can

be called, not just parents.  Add a comparison to getattr()
which has the same search order but also includes the type
itself.
This commit is contained in:
Raymond Hettinger 2009-02-24 23:30:43 +00:00
parent 886687dcda
commit 4d9a823cb6
2 changed files with 23 additions and 19 deletions

View File

@ -1045,11 +1045,14 @@ are always available. They are listed here in alphabetical order.
.. function:: super([type[, object-or-type]])
Return a proxy object that delegates method calls to a parent class of
*type*. This is useful for accessing inherited methods that have been
overriden in a child class. The search order for parent classes is
determined by the ``__mro__`` attribute of the *type* and can change
whenever the parent classes are updated.
Return a proxy object that delegates method calls to a parent or sibling
class of *type*. This is useful for accessing inherited methods that have
been overridden in a class. The search order is same as that used by
:func:`getattr` except that the *type* itself is skipped.
The ``__mro__`` attribute of the *type* lists the method resolution search
order used by both func:`getattr` and :func:`super`. The attribue is dynamic
and can change whenever the inheritance hierarchy is updated.
If the second argument is omitted the super object returned is unbound. If
the second argument is an object, ``isinstance(obj, type)`` must be true. If
@ -1061,14 +1064,15 @@ are always available. They are listed here in alphabetical order.
naming them explicitly, thus making the code more maintainable. This use
closely parallels the use of "super" in other programming languages.
The second use case is to support cooperative multiple inheritence in a
The second use case is to support cooperative multiple inheritance in a
dynamic execution environment. This use case is unique to Python and is
not found in statically compiled languages or languages that only support
single inheritance. This makes in possible to implement "diamond diagrams"
where multiple base classes implement the same method. Good design dictates
that this method have the same calling signature in every case (because the
order of parent calls is determined at runtime and because that order adapts
to changes in the class hierarchy).
order of calls is determined at runtime, because that order adapts
to changes in the class hierarchy, and because that order can include
sibling classes that are unknown prior to runtime).
For both use cases, a typical superclass call looks like this::
@ -1079,7 +1083,7 @@ are always available. They are listed here in alphabetical order.
Note that :func:`super` is implemented as part of the binding process for
explicit dotted attribute lookups such as ``super().__getitem__(name)``.
It does so by implementing its own :meth:`__getattribute__` method for searching
parent classes in a predictable order that supports cooperative multiple inheritance.
classes in a predictable order that supports cooperative multiple inheritance.
Accordingly, :func:`super` is undefined for implicit lookups using statements or
operators such as ``super()[name]``.

View File

@ -390,7 +390,7 @@ class HTMLRepr(Repr):
# needed to make any special characters, so show a raw string.
return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
r'<font color="#c040c0">\1</font>',
r'<span class="">\1</span>',
self.escape(testrepr))
repr_str = repr_string
@ -417,7 +417,7 @@ class HTMLDoc(Doc):
return '''
<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: %s</title>
</head><body bgcolor="#f0f0f8">
</head><body>
%s
</body></html>''' % (title, contents)
@ -456,7 +456,7 @@ class HTMLDoc(Doc):
def bigsection(self, title, *args):
"""Format a section with a big heading."""
title = '<big><strong>%s</strong></big>' % title
title = '<span class="bigsection">%s</span>' % title
return self.section(title, *args)
def preformat(self, text):
@ -477,7 +477,7 @@ class HTMLDoc(Doc):
result = result + '</td>'
return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result
def grey(self, text): return '<font color="#909090">%s</font>' % text
def grey(self, text): return '<span class="grey">%s</span>' % text
def namelink(self, name, *dicts):
"""Make a link for an identifier, given name-to-URL mappings."""
@ -508,7 +508,7 @@ class HTMLDoc(Doc):
else:
url = '%s.html' % name
if ispackage:
text = '<strong>%s</strong>&nbsp;(package)' % name
text = '<span class="package">%s</span>&nbsp;(package)' % name
else:
text = name
return '<a href="%s">%s</a>' % (url, text)
@ -542,7 +542,7 @@ class HTMLDoc(Doc):
elif text[end:end+1] == '(':
results.append(self.namelink(name, methods, funcs, classes))
elif selfdot:
results.append('self.<strong>%s</strong>' % name)
results.append('self.<span class="selfdot">%s</span>' % name)
else:
results.append(self.namelink(name, classes))
here = end
@ -557,14 +557,14 @@ class HTMLDoc(Doc):
for entry in tree:
if type(entry) is type(()):
c, bases = entry
result = result + '<dt><font face="helvetica, arial">'
result = result + '<dt class="classlink">'
result = result + self.classlink(c, modname)
if bases and bases != (parent,):
parents = []
for base in bases:
parents.append(self.classlink(base, modname))
result = result + '(' + ', '.join(parents) + ')'
result = result + '\n</font></dt>'
result = result + '\n</dt>'
elif type(entry) is type([]):
result = result + '<dd>\n%s</dd>\n' % self.formattree(
entry, modname, c)
@ -581,10 +581,10 @@ class HTMLDoc(Doc):
links = []
for i in range(len(parts)-1):
links.append(
'<a href="%s.html"><font color="#ffffff">%s</font></a>' %
'<a href="%s.html" class="links">%s</a>' %
('.'.join(parts[:i+1]), parts[i]))
linkedname = '.'.join(links + parts[-1:])
head = '<big><big><strong>%s</strong></big></big>' % linkedname
head = '<span class="linkedname">%s</span>' % linkedname
try:
path = inspect.getabsfile(object)
url = path