gh-101100: Improve documentation for attributes on instance methods (#112832)

This commit is contained in:
Alex Waygood 2023-12-08 13:18:53 +00:00 committed by GitHub
parent e4c0876033
commit ed21d0c1f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 40 deletions

View File

@ -492,7 +492,7 @@ attributes (see :ref:`import-mod-attrs` for module attributes):
Methods implemented via descriptors that also pass one of the other tests Methods implemented via descriptors that also pass one of the other tests
return ``False`` from the :func:`ismethoddescriptor` test, simply because the return ``False`` from the :func:`ismethoddescriptor` test, simply because the
other tests promise more -- you can, e.g., count on having the other tests promise more -- you can, e.g., count on having the
:ref:`__func__ <instance-methods>` attribute (etc) when an object passes :attr:`~method.__func__` attribute (etc) when an object passes
:func:`ismethod`. :func:`ismethod`.

View File

@ -5328,25 +5328,30 @@ Methods
.. index:: pair: object; method .. index:: pair: object; method
Methods are functions that are called using the attribute notation. There are Methods are functions that are called using the attribute notation. There are
two flavors: built-in methods (such as :meth:`append` on lists) and class two flavors: :ref:`built-in methods <builtin-methods>` (such as :meth:`append`
instance methods. Built-in methods are described with the types that support on lists) and :ref:`class instance method <instance-methods>`.
them. Built-in methods are described with the types that support them.
If you access a method (a function defined in a class namespace) through an If you access a method (a function defined in a class namespace) through an
instance, you get a special object: a :dfn:`bound method` (also called instance, you get a special object: a :dfn:`bound method` (also called
:dfn:`instance method`) object. When called, it will add the ``self`` argument :ref:`instance method <instance-methods>`) object. When called, it will add
the ``self`` argument
to the argument list. Bound methods have two special read-only attributes: to the argument list. Bound methods have two special read-only attributes:
``m.__self__`` is the object on which the method operates, and ``m.__func__`` is :attr:`m.__self__ <method.__self__>` is the object on which the method
operates, and :attr:`m.__func__ <method.__func__>` is
the function implementing the method. Calling ``m(arg-1, arg-2, ..., arg-n)`` the function implementing the method. Calling ``m(arg-1, arg-2, ..., arg-n)``
is completely equivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ..., is completely equivalent to calling ``m.__func__(m.__self__, arg-1, arg-2, ...,
arg-n)``. arg-n)``.
Like function objects, bound method objects support getting arbitrary Like :ref:`function objects <user-defined-funcs>`, bound method objects support
getting arbitrary
attributes. However, since method attributes are actually stored on the attributes. However, since method attributes are actually stored on the
underlying function object (``meth.__func__``), setting method attributes on underlying function object (:attr:`method.__func__`), setting method attributes on
bound methods is disallowed. Attempting to set an attribute on a method bound methods is disallowed. Attempting to set an attribute on a method
results in an :exc:`AttributeError` being raised. In order to set a method results in an :exc:`AttributeError` being raised. In order to set a method
attribute, you need to explicitly set it on the underlying function object:: attribute, you need to explicitly set it on the underlying function object:
.. doctest::
>>> class C: >>> class C:
... def method(self): ... def method(self):
@ -5361,7 +5366,7 @@ attribute, you need to explicitly set it on the underlying function object::
>>> c.method.whoami >>> c.method.whoami
'my name is method' 'my name is method'
See :ref:`types` for more information. See :ref:`instance-methods` for more information.
.. index:: object; code, code object .. index:: object; code, code object

View File

@ -519,6 +519,8 @@ These are the types to which the function call operation (see section
:ref:`calls`) can be applied: :ref:`calls`) can be applied:
.. _user-defined-funcs:
User-defined functions User-defined functions
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
@ -654,43 +656,64 @@ callable object (normally a user-defined function).
single: __name__ (method attribute) single: __name__ (method attribute)
single: __module__ (method attribute) single: __module__ (method attribute)
Special read-only attributes: :attr:`__self__` is the class instance object, Special read-only attributes:
:attr:`__func__` is the function object; :attr:`__doc__` is the method's
documentation (same as ``__func__.__doc__``); :attr:`~definition.__name__` is the .. list-table::
method name (same as ``__func__.__name__``); :attr:`__module__` is the
name of the module the method was defined in, or ``None`` if unavailable. * - .. attribute:: method.__self__
- Refers to the class instance object to which the method is
:ref:`bound <method-binding>`
* - .. attribute:: method.__func__
- Refers to the original function object
* - .. attribute:: method.__doc__
- The method's documentation (same as :attr:`!method.__func__.__doc__`).
A :class:`string <str>` if the original function had a docstring, else
``None``.
* - .. attribute:: method.__name__
- The name of the method (same as :attr:`!method.__func__.__name__`)
* - .. attribute:: method.__module__
- The name of the module the method was defined in, or ``None`` if
unavailable.
Methods also support accessing (but not setting) the arbitrary function Methods also support accessing (but not setting) the arbitrary function
attributes on the underlying function object. attributes on the underlying :ref:`function object <user-defined-funcs>`.
User-defined method objects may be created when getting an attribute of a User-defined method objects may be created when getting an attribute of a
class (perhaps via an instance of that class), if that attribute is a class (perhaps via an instance of that class), if that attribute is a
user-defined function object or a class method object. user-defined :ref:`function object <user-defined-funcs>` or a
:class:`classmethod` object.
.. _method-binding:
When an instance method object is created by retrieving a user-defined When an instance method object is created by retrieving a user-defined
function object from a class via one of its instances, its :ref:`function object <user-defined-funcs>` from a class via one of its
:attr:`__self__` attribute is the instance, and the method object is said instances, its :attr:`~method.__self__` attribute is the instance, and the
to be bound. The new method's :attr:`__func__` attribute is the original method object is said to be *bound*. The new method's :attr:`~method.__func__`
function object. attribute is the original function object.
When an instance method object is created by retrieving a class method When an instance method object is created by retrieving a :class:`classmethod`
object from a class or instance, its :attr:`__self__` attribute is the object from a class or instance, its :attr:`~method.__self__` attribute is the
class itself, and its :attr:`__func__` attribute is the function object class itself, and its :attr:`~method.__func__` attribute is the function object
underlying the class method. underlying the class method.
When an instance method object is called, the underlying function When an instance method object is called, the underlying function
(:attr:`__func__`) is called, inserting the class instance (:attr:`~method.__func__`) is called, inserting the class instance
(:attr:`__self__`) in front of the argument list. For instance, when (:attr:`~method.__self__`) in front of the argument list. For instance, when
:class:`!C` is a class which contains a definition for a function :class:`!C` is a class which contains a definition for a function
:meth:`!f`, and ``x`` is an instance of :class:`!C`, calling ``x.f(1)`` is :meth:`!f`, and ``x`` is an instance of :class:`!C`, calling ``x.f(1)`` is
equivalent to calling ``C.f(x, 1)``. equivalent to calling ``C.f(x, 1)``.
When an instance method object is derived from a class method object, the When an instance method object is derived from a :class:`classmethod` object, the
"class instance" stored in :attr:`__self__` will actually be the class "class instance" stored in :attr:`~method.__self__` will actually be the class
itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to itself, so that calling either ``x.f(1)`` or ``C.f(1)`` is equivalent to
calling ``f(C,1)`` where ``f`` is the underlying function. calling ``f(C,1)`` where ``f`` is the underlying function.
Note that the transformation from function object to instance method Note that the transformation from :ref:`function object <user-defined-funcs>`
to instance method
object happens each time the attribute is retrieved from the instance. In object happens each time the attribute is retrieved from the instance. In
some cases, a fruitful optimization is to assign the attribute to a local some cases, a fruitful optimization is to assign the attribute to a local
variable and call that local variable. Also notice that this variable and call that local variable. Also notice that this
@ -774,6 +797,8 @@ set to ``None`` (but see the next item); :attr:`__module__` is the name of
the module the function was defined in or ``None`` if unavailable. the module the function was defined in or ``None`` if unavailable.
.. _builtin-methods:
Built-in methods Built-in methods
^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
@ -785,8 +810,9 @@ Built-in methods
This is really a different disguise of a built-in function, this time containing This is really a different disguise of a built-in function, this time containing
an object passed to the C function as an implicit extra argument. An example of an object passed to the C function as an implicit extra argument. An example of
a built-in method is ``alist.append()``, assuming *alist* is a list object. In a built-in method is ``alist.append()``, assuming *alist* is a list object. In
this case, the special read-only attribute :attr:`__self__` is set to the object this case, the special read-only attribute :attr:`!__self__` is set to the object
denoted by *alist*. denoted by *alist*. (The attribute has the same semantics as it does with
:attr:`other instance methods <method.__self__>`.)
Classes Classes
@ -901,8 +927,9 @@ https://www.python.org/download/releases/2.3/mro/.
When a class attribute reference (for class :class:`!C`, say) would yield a When a class attribute reference (for class :class:`!C`, say) would yield a
class method object, it is transformed into an instance method object whose class method object, it is transformed into an instance method object whose
:attr:`__self__` attribute is :class:`!C`. When it would yield a static :attr:`~method.__self__` attribute is :class:`!C`.
method object, it is transformed into the object wrapped by the static method When it would yield a :class:`staticmethod` object,
it is transformed into the object wrapped by the static method
object. See section :ref:`descriptors` for another way in which attributes object. See section :ref:`descriptors` for another way in which attributes
retrieved from a class may differ from those actually contained in its retrieved from a class may differ from those actually contained in its
:attr:`~object.__dict__`. :attr:`~object.__dict__`.
@ -970,7 +997,7 @@ in which attribute references are searched. When an attribute is not found
there, and the instance's class has an attribute by that name, the search there, and the instance's class has an attribute by that name, the search
continues with the class attributes. If a class attribute is found that is a continues with the class attributes. If a class attribute is found that is a
user-defined function object, it is transformed into an instance method user-defined function object, it is transformed into an instance method
object whose :attr:`__self__` attribute is the instance. Static method and object whose :attr:`~method.__self__` attribute is the instance. Static method and
class method objects are also transformed; see above under "Classes". See class method objects are also transformed; see above under "Classes". See
section :ref:`descriptors` for another way in which attributes of a class section :ref:`descriptors` for another way in which attributes of a class
retrieved via its instances may differ from the objects actually stored in retrieved via its instances may differ from the objects actually stored in

View File

@ -769,8 +769,10 @@ data from a string buffer instead, and pass it as an argument.
or arithmetic operators, and assigning such a "pseudo-file" to sys.stdin will or arithmetic operators, and assigning such a "pseudo-file" to sys.stdin will
not cause the interpreter to read further input from it.) not cause the interpreter to read further input from it.)
Instance method objects have attributes, too: ``m.__self__`` is the instance :ref:`Instance method objects <instance-methods>` have attributes, too:
object with the method :meth:`!m`, and ``m.__func__`` is the function object :attr:`m.__self__ <method.__self__>` is the instance
object with the method :meth:`!m`, and :attr:`m.__func__ <method.__func__>` is
the :ref:`function object <user-defined-funcs>`
corresponding to the method. corresponding to the method.

View File

@ -1678,8 +1678,8 @@ Some smaller changes made to the core Python language are:
* Instance method objects have new attributes for the object and function * Instance method objects have new attributes for the object and function
comprising the method; the new synonym for :attr:`!im_self` is comprising the method; the new synonym for :attr:`!im_self` is
:ref:`__self__ <instance-methods>`, and :attr:`!im_func` is also available as :attr:`~method.__self__`, and :attr:`!im_func` is also available as
:ref:`__func__ <instance-methods>`. :attr:`~method.__func__`.
The old names are still supported in Python 2.6, but are gone in 3.0. The old names are still supported in Python 2.6, but are gone in 3.0.
* An obscure change: when you use the :func:`locals` function inside a * An obscure change: when you use the :func:`locals` function inside a

View File

@ -858,9 +858,10 @@ Some smaller changes made to the core Python language are:
.. XXX bytearray doesn't seem to be documented .. XXX bytearray doesn't seem to be documented
* When using ``@classmethod`` and ``@staticmethod`` to wrap * When using :class:`@classmethod <classmethod>` and
:class:`@staticmethod <staticmethod>` to wrap
methods as class or static methods, the wrapper object now methods as class or static methods, the wrapper object now
exposes the wrapped function as their :ref:`__func__ <instance-methods>` exposes the wrapped function as their :attr:`~method.__func__`
attribute. attribute.
(Contributed by Amaury Forgeot d'Arc, after a suggestion by (Contributed by Amaury Forgeot d'Arc, after a suggestion by
George Sakkis; :issue:`5982`.) George Sakkis; :issue:`5982`.)