mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
[3.13] gh-120452: improve documentation about private name mangling (GH-120451) (#121715)
gh-120452: improve documentation about private name mangling (GH-120451)
(cherry picked from commit f4d6e45c1e
)
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
parent
b9cfb812e2
commit
4af9c05e78
3 changed files with 69 additions and 15 deletions
|
@ -1741,11 +1741,31 @@ but effective way to define class private variables. Any identifier of the form
|
||||||
is textually replaced with ``_classname__spam``, where ``classname`` is the
|
is textually replaced with ``_classname__spam``, where ``classname`` is the
|
||||||
current class name with any leading underscores stripped.
|
current class name with any leading underscores stripped.
|
||||||
|
|
||||||
This doesn't guarantee privacy: an outside user can still deliberately access
|
The identifier can be used unchanged within the class, but to access it outside
|
||||||
the "_classname__spam" attribute, and private values are visible in the object's
|
the class, the mangled name must be used:
|
||||||
``__dict__``. Many Python programmers never bother to use private variable
|
|
||||||
names at all.
|
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
class A:
|
||||||
|
def __one(self):
|
||||||
|
return 1
|
||||||
|
def two(self):
|
||||||
|
return 2 * self.__one()
|
||||||
|
|
||||||
|
class B(A):
|
||||||
|
def three(self):
|
||||||
|
return 3 * self._A__one()
|
||||||
|
|
||||||
|
four = 4 * A()._A__one()
|
||||||
|
|
||||||
|
In particular, this does not guarantee privacy since an outside user can still
|
||||||
|
deliberately access the private attribute; many Python programmers never bother
|
||||||
|
to use private variable names at all.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
The :ref:`private name mangling specifications <private-name-mangling>`
|
||||||
|
for details and special cases.
|
||||||
|
|
||||||
My class defines __del__ but it is not called when I delete the object.
|
My class defines __del__ but it is not called when I delete the object.
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
|
|
@ -83,18 +83,47 @@ exception.
|
||||||
pair: name; mangling
|
pair: name; mangling
|
||||||
pair: private; names
|
pair: private; names
|
||||||
|
|
||||||
**Private name mangling:** When an identifier that textually occurs in a class
|
Private name mangling
|
||||||
definition begins with two or more underscore characters and does not end in two
|
^^^^^^^^^^^^^^^^^^^^^
|
||||||
or more underscores, it is considered a :dfn:`private name` of that class.
|
|
||||||
Private names are transformed to a longer form before code is generated for
|
|
||||||
them. The transformation inserts the class name, with leading underscores
|
|
||||||
removed and a single underscore inserted, in front of the name. For example,
|
|
||||||
the identifier ``__spam`` occurring in a class named ``Ham`` will be transformed
|
|
||||||
to ``_Ham__spam``. This transformation is independent of the syntactical
|
|
||||||
context in which the identifier is used. If the transformed name is extremely
|
|
||||||
long (longer than 255 characters), implementation defined truncation may happen.
|
|
||||||
If the class name consists only of underscores, no transformation is done.
|
|
||||||
|
|
||||||
|
When an identifier that textually occurs in a class definition begins with two
|
||||||
|
or more underscore characters and does not end in two or more underscores, it
|
||||||
|
is considered a :dfn:`private name` of that class.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
The :ref:`class specifications <class>`.
|
||||||
|
|
||||||
|
More precisely, private names are transformed to a longer form before code is
|
||||||
|
generated for them. If the transformed name is longer than 255 characters,
|
||||||
|
implementation-defined truncation may happen.
|
||||||
|
|
||||||
|
The transformation is independent of the syntactical context in which the
|
||||||
|
identifier is used but only the following private identifiers are mangled:
|
||||||
|
|
||||||
|
- Any name used as the name of a variable that is assigned or read or any
|
||||||
|
name of an attribute being accessed.
|
||||||
|
|
||||||
|
The ``__name__`` attribute of nested functions, classes, and type aliases
|
||||||
|
is however not mangled.
|
||||||
|
|
||||||
|
- The name of imported modules, e.g., ``__spam`` in ``import __spam``.
|
||||||
|
If the module is part of a package (i.e., its name contains a dot),
|
||||||
|
the name is *not* mangled, e.g., the ``__foo`` in ``import __foo.bar``
|
||||||
|
is not mangled.
|
||||||
|
|
||||||
|
- The name of an imported member, e.g., ``__f`` in ``from spam import __f``.
|
||||||
|
|
||||||
|
The transformation rule is defined as follows:
|
||||||
|
|
||||||
|
- The class name, with leading underscores removed and a single leading
|
||||||
|
underscore inserted, is inserted in front of the identifier, e.g., the
|
||||||
|
identifier ``__spam`` occurring in a class named ``Foo``, ``_Foo`` or
|
||||||
|
``__Foo`` is transformed to ``_Foo__spam``.
|
||||||
|
|
||||||
|
- If the class name consists only of underscores, the transformation is the
|
||||||
|
identity, e.g., the identifier ``__spam`` occurring in a class named ``_``
|
||||||
|
or ``__`` is left as is.
|
||||||
|
|
||||||
.. _atom-literals:
|
.. _atom-literals:
|
||||||
|
|
||||||
|
|
|
@ -688,6 +688,11 @@ current class name with leading underscore(s) stripped. This mangling is done
|
||||||
without regard to the syntactic position of the identifier, as long as it
|
without regard to the syntactic position of the identifier, as long as it
|
||||||
occurs within the definition of a class.
|
occurs within the definition of a class.
|
||||||
|
|
||||||
|
.. seealso::
|
||||||
|
|
||||||
|
The :ref:`private name mangling specifications <private-name-mangling>`
|
||||||
|
for details and special cases.
|
||||||
|
|
||||||
Name mangling is helpful for letting subclasses override methods without
|
Name mangling is helpful for letting subclasses override methods without
|
||||||
breaking intraclass method calls. For example::
|
breaking intraclass method calls. For example::
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue