@@ -90,20 +90,71 @@ or more underscore characters and does not end in two or more underscores, it
90
90
is considered a :dfn: `private name ` of that class.
91
91
92
92
More precisely, private names are transformed to a longer form before code is
93
- generated for them. The transformation rule is defined as follows:
93
+ generated for them. If the transformed name is longer than 255 characters,
94
+ implementation-defined truncation may happen.
94
95
95
- - If the class name consists only of underscores, no transformation is done,
96
- e.g., the identifier ``__spam `` occurring in a class named ``_ `` or ``__ ``
97
- is left as is.
96
+ The transformation is independent of the syntactical context in which the
97
+ identifier is used and the transformation rule is defined as follows:
98
+
99
+ - If the class name consists only of underscores, the transformation is the
100
+ identity, e.g., the identifier ``__spam `` occurring in a class named ``_ ``
101
+ or ``__ `` is left as is.
98
102
99
103
- Otherwise, the transformation inserts the class name, with leading
100
104
underscores removed and a single underscore inserted, in front of
101
105
the identifier, e.g., the identifier ``__spam `` occurring in a class
102
- named ``Ham ``, ``_Ham `` or ``__Ham `` is transformed to ``_Ham__spam ``.
106
+ named ``Foo ``, ``_Foo `` or ``__Foo `` is transformed to ``_Foo__spam ``.
103
107
104
- The transformation is independent of the syntactical context in which the
105
- identifier is used. Nonetheless, if the transformed name is extremely long
106
- (longer than 255 characters), implementation-defined truncation may happen.
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: `ModuleNotFoundError ` (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 ::
129
+
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()
139
+
140
+ The corresponding private member is accessed by its defining class using
141
+ its non-transformed name. On the other hand, the transformed name must be
142
+ used to access the private member *externally * (e.g., in a function or in
143
+ a subclass):
144
+
145
+ .. code-block :: python
146
+
147
+ class A :
148
+ def __one (self ):
149
+ return 1
150
+ def two (self ):
151
+ return 2 * self .__one()
152
+
153
+ class B (A ):
154
+ def three (self ):
155
+ return 3 * self ._A__one()
156
+
157
+ four = A()._A__one()
107
158
108
159
109
160
.. _atom-literals :
0 commit comments