I am experiencing an obscure (to me) effect of dundered scoping, and trying to work out the rule for it:
#!/usr/bin/env python3
stuff = "the things"
__MORE_STUFF = "even more"
class Thing:
def __init__(self):
global __MORE_STUFF # doesn't help
print(stuff) # is OK
print(__MORE_STUFF) # fail!
Thing()
results in
$ python3 dunder.py
the things
Traceback (most recent call last):
File "dunder.py", line 12, in <module>
Thing()
File "dunder.py", line 10, in __init__
print(__MORE_STUFF) # fail!
NameError: name '_Thing__MORE_STUFF' is not defined
What is supposed to be a module-global variable is being treated as a class-level property - which, being undefined, is flagged as being undefined.
I've been trying to look through the documentation for this, but I cannot seem to work out what the rule is.
Can anyone point me to the appropriate documentation?
CodePudding user response:
The documentation refers to such names as class-private names:
__*
Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes. See section Identifiers (Names).
Since subclassing isn't something that applies to modules (at least, not to the extent that the language provides any tools or recommendations regarding how you might go about it), there's no need to use class-private names where _
-prefixed names will do.
#!/usr/bin/env python3
stuff = "the things"
_MORE_STUFF = "even more"
class Thing:
def __init__(self):
print(stuff) # is OK
print(_MORE_STUFF)
Thing()