Dundered global variable cannot be accessed inside a class method

Question:

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?

Asked By: taifwa

||

Answers:

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()
Answered By: chepner
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.