@@ -83,12 +83,17 @@ exception.
83
83
pair: name; mangling
84
84
pair: private; names
85
85
86
- .. rubric :: Private name mangling
86
+ Private name mangling
87
+ ^^^^^^^^^^^^^^^^^^^^^
87
88
88
89
When an identifier that textually occurs in a class definition begins with two
89
90
or more underscore characters and does not end in two or more underscores, it
90
91
is considered a :dfn: `private name ` of that class.
91
92
93
+ .. seealso ::
94
+
95
+ The :ref: `tutorial on classes <_tut-classdefinition >` for more details.
96
+
92
97
More precisely, private names are transformed to a longer form before code is
93
98
generated for them. If the transformed name is longer than 255 characters,
94
99
implementation-defined truncation may happen.
@@ -105,37 +110,9 @@ identifier is used and the transformation rule is defined as follows:
105
110
the identifier, e.g., the identifier ``__spam `` occurring in a class
106
111
named ``Foo ``, ``_Foo `` or ``__Foo `` is transformed to ``_Foo__spam ``.
107
112
108
- For identifiers declared using :keyword: `import ` statements, this rule is
109
- slightly different. Indeed, importing a module with a private name directly
110
- in a class body raises a :exc: `ModuleN
8000
otFoundError ` (unless the class name
111
- only consists of underscores), as illustrated by the following example:
112
-
113
- .. code-block :: python
114
-
115
- class Foo :
116
- import __spam # raises ModuleNotFoundError at runtime
117
-
118
- This restriction can be lifted by using the :func: `__import__ ` function,
119
- in which case the transformation rule is applied normally:
120
-
121
- .. code-block :: python
122
-
123
- class Foo :
124
- __spam = __import__ (" __spam" )
125
-
126
- Foo._Foo__spam.do()
127
-
128
- .. note ::
113
+ .. _private-name-mangling-access :
129
114
130
- This restriction does not apply to modules imported as submodules of
131
- private packages, e.g.:
132
-
133
- .. code-block :: python
134
-
135
- class Foo :
136
- import __spam.util
137
-
138
- Foo._Foo__spam.util.do()
115
+ .. rubric :: Accessing members with mangled names
139
116
140
117
The corresponding private member is accessed by its defining class using
141
118
its non-transformed name. On the other hand, the transformed name must be
@@ -156,6 +133,82 @@ a subclass):
156
133
157
134
four = 4 * A()._A__one()
158
135
136
+ .. _private-name-mangling-imports :
137
+
138
+ .. rubric :: Mangled names in imports
139
+
140
+ For identifiers declared using :keyword: `import ` statements, the mangling
141
+ rule is slightly different. Throughout this paragraph, assume that we have
142
+ the following filesystem layout and, unless stated otherwise, the code snippets
143
+ are in the ``__main__.py `` file.
144
+
145
+ .. code-block ::
146
+
147
+ .
148
+ ├── __main__.py
149
+ ├── __pkg
150
+ │ ├── __init__.py
151
+ │ └── mod.py
152
+ ├── __bar.py
153
+ ├── __foo.py
154
+ └── _Bar__bar.py
155
+
156
+ Importing a module with a private name directly in a class body may raise
157
+ a :exc: `ModuleNotFoundError `, as illustrated by the following example:
158
+
159
+ .. code-block :: python
160
+
161
+ class Bar :
162
+ # equivalent to import _Bar__bar
163
+ import __bar
164
+ print (Bar._Bar__bar) # <module '_Bar__bar' from '/_Bar__bar.py'>
165
+
166
+ class Foo
8000
:
167
+ # raises a ModuleNotFoundError at runtime since the interpreter
168
+ # tries to import '_Foo__foo' instead of '__foo'
169
+ import __foo
170
+
171
+ If the ``__foo `` module is needed inside the `Foo ` class, the import can
172
+ be performed via the :func: `__import__ ` function, in which case the usual
173
+ transformation rule is applied (a similar logic applies to :func: `getattr `,
174
+ :func: `setattr ` and :func: `delattr `, see ):
175
+
176
+ .. code-block :: python
177
+
178
+ class Bar :
179
+ # explicitly import '__bar' instead of '_Bar__bar'
180
+ __bar = __import__ (" __bar" )
181
+ print (Bar._Bar__bar) # <module '__bar' from '/__bar.py'>
182
+
183
+ class Foo :
184
+ # explicitly import '__foo' instead of '_Foo__foo'
185
+ __foo = __import__ (" __foo" )
186
+ print (Foo._Foo__foo) # <module '__foo' from '/__foo.py'>
187
+
188
+ This restriction does not apply to modules imported as submodules of packages
189
+ with private names, e.g.:
190
+
191
+ .. code-block :: python
192
+
193
+ class Foo :
194
+ import __pkg.mod
195
+
196
+ print (Foo._Foo__pkg) # <module '__pkg' from '/__pkg/__init__.py'>
197
+ print (Foo._Foo__pkg.mod) # <module '__pkg.mod' from '/__pkg/mod.py'>
198
+
199
+ Note that a class whose name only consists of underscores does not
200
+ suffer from those restrictions on :keyword: `import ` statements:
201
+
202
+ .. code-block :: python
203
+
204
+ class _ :
205
+ import __bar # imports '__bar'
206
+ import __foo # imports '__foo'
207
+ import __pkg # imports '__foo'
208
+
209
+ print (_.__bar) # <module '__bar' from '/__bar.py'>
210
+ print (_.__foo) # <module '__foo' from '/__foo.py'>
211
+ print (_.__pkg) # <module '__pkg' from '/__pkg/__init__.py'>
159
212
160
213
.. _atom-literals :
161
214
0 commit comments