Kaydet (Commit) 4d9a823c authored tarafından Raymond Hettinger's avatar Raymond Hettinger

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.
üst 886687dc
...@@ -1045,11 +1045,14 @@ are always available. They are listed here in alphabetical order. ...@@ -1045,11 +1045,14 @@ are always available. They are listed here in alphabetical order.
.. function:: super([type[, object-or-type]]) .. function:: super([type[, object-or-type]])
Return a proxy object that delegates method calls to a parent class of Return a proxy object that delegates method calls to a parent or sibling
*type*. This is useful for accessing inherited methods that have been class of *type*. This is useful for accessing inherited methods that have
overriden in a child class. The search order for parent classes is been overridden in a class. The search order is same as that used by
determined by the ``__mro__`` attribute of the *type* and can change :func:`getattr` except that the *type* itself is skipped.
whenever the parent classes are updated.
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 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 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. ...@@ -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 naming them explicitly, thus making the code more maintainable. This use
closely parallels the use of "super" in other programming languages. 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 dynamic execution environment. This use case is unique to Python and is
not found in statically compiled languages or languages that only support not found in statically compiled languages or languages that only support
single inheritance. This makes in possible to implement "diamond diagrams" single inheritance. This makes in possible to implement "diamond diagrams"
where multiple base classes implement the same method. Good design dictates where multiple base classes implement the same method. Good design dictates
that this method have the same calling signature in every case (because the 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 order of calls is determined at runtime, because that order adapts
to changes in the class hierarchy). 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:: 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. ...@@ -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 Note that :func:`super` is implemented as part of the binding process for
explicit dotted attribute lookups such as ``super().__getitem__(name)``. explicit dotted attribute lookups such as ``super().__getitem__(name)``.
It does so by implementing its own :meth:`__getattribute__` method for searching 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 Accordingly, :func:`super` is undefined for implicit lookups using statements or
operators such as ``super()[name]``. operators such as ``super()[name]``.
......
...@@ -390,7 +390,7 @@ class HTMLRepr(Repr): ...@@ -390,7 +390,7 @@ class HTMLRepr(Repr):
# needed to make any special characters, so show a raw string. # needed to make any special characters, so show a raw string.
return 'r' + testrepr[0] + self.escape(test) + testrepr[0] return 'r' + testrepr[0] + self.escape(test) + testrepr[0]
return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)', return re.sub(r'((\\[\\abfnrtv\'"]|\\[0-9]..|\\x..|\\u....)+)',
r'<font color="#c040c0">\1</font>', r'<span class="">\1</span>',
self.escape(testrepr)) self.escape(testrepr))
repr_str = repr_string repr_str = repr_string
...@@ -417,7 +417,7 @@ class HTMLDoc(Doc): ...@@ -417,7 +417,7 @@ class HTMLDoc(Doc):
return ''' return '''
<!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!doctype html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: %s</title> <html><head><title>Python: %s</title>
</head><body bgcolor="#f0f0f8"> </head><body>
%s %s
</body></html>''' % (title, contents) </body></html>''' % (title, contents)
...@@ -456,7 +456,7 @@ class HTMLDoc(Doc): ...@@ -456,7 +456,7 @@ class HTMLDoc(Doc):
def bigsection(self, title, *args): def bigsection(self, title, *args):
"""Format a section with a big heading.""" """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) return self.section(title, *args)
def preformat(self, text): def preformat(self, text):
...@@ -477,7 +477,7 @@ class HTMLDoc(Doc): ...@@ -477,7 +477,7 @@ class HTMLDoc(Doc):
result = result + '</td>' result = result + '</td>'
return '<table width="100%%" summary="list"><tr>%s</tr></table>' % result 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): def namelink(self, name, *dicts):
"""Make a link for an identifier, given name-to-URL mappings.""" """Make a link for an identifier, given name-to-URL mappings."""
...@@ -508,7 +508,7 @@ class HTMLDoc(Doc): ...@@ -508,7 +508,7 @@ class HTMLDoc(Doc):
else: else:
url = '%s.html' % name url = '%s.html' % name
if ispackage: if ispackage:
text = '<strong>%s</strong>&nbsp;(package)' % name text = '<span class="package">%s</span>&nbsp;(package)' % name
else: else:
text = name text = name
return '<a href="%s">%s</a>' % (url, text) return '<a href="%s">%s</a>' % (url, text)
...@@ -542,7 +542,7 @@ class HTMLDoc(Doc): ...@@ -542,7 +542,7 @@ class HTMLDoc(Doc):
elif text[end:end+1] == '(': elif text[end:end+1] == '(':
results.append(self.namelink(name, methods, funcs, classes)) results.append(self.namelink(name, methods, funcs, classes))
elif selfdot: elif selfdot:
results.append('self.<strong>%s</strong>' % name) results.append('self.<span class="selfdot">%s</span>' % name)
else: else:
results.append(self.namelink(name, classes)) results.append(self.namelink(name, classes))
here = end here = end
...@@ -557,14 +557,14 @@ class HTMLDoc(Doc): ...@@ -557,14 +557,14 @@ class HTMLDoc(Doc):
for entry in tree: for entry in tree:
if type(entry) is type(()): if type(entry) is type(()):
c, bases = entry c, bases = entry
result = result + '<dt><font face="helvetica, arial">' result = result + '<dt class="classlink">'
result = result + self.classlink(c, modname) result = result + self.classlink(c, modname)
if bases and bases != (parent,): if bases and bases != (parent,):
parents = [] parents = []
for base in bases: for base in bases:
parents.append(self.classlink(base, modname)) parents.append(self.classlink(base, modname))
result = result + '(' + ', '.join(parents) + ')' result = result + '(' + ', '.join(parents) + ')'
result = result + '\n</font></dt>' result = result + '\n</dt>'
elif type(entry) is type([]): elif type(entry) is type([]):
result = result + '<dd>\n%s</dd>\n' % self.formattree( result = result + '<dd>\n%s</dd>\n' % self.formattree(
entry, modname, c) entry, modname, c)
...@@ -581,10 +581,10 @@ class HTMLDoc(Doc): ...@@ -581,10 +581,10 @@ class HTMLDoc(Doc):
links = [] links = []
for i in range(len(parts)-1): for i in range(len(parts)-1):
links.append( 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])) ('.'.join(parts[:i+1]), parts[i]))
linkedname = '.'.join(links + parts[-1:]) linkedname = '.'.join(links + parts[-1:])
head = '<big><big><strong>%s</strong></big></big>' % linkedname head = '<span class="linkedname">%s</span>' % linkedname
try: try:
path = inspect.getabsfile(object) path = inspect.getabsfile(object)
url = path url = path
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment