2

When I created a module-level variable with __ and tried to access it inside a method of a class (using global keyword) the name-mangling occured.

Let me show an example:

__test = 'asd'  # module level variable with __


class TestClass(object):
    def test(self):
        global __test
        print(__test)  # trying to access this variable


a = TestClass()
a.test()

Interpreter raised an error:

NameError: name '_TestClass__test' is not defined

So as we can see it tried to name-mangle __test into _TestClass__test.

I thought that name-mangling should be used only for class variables (when I access them with self or class name).

Is it a well-defined behaviour that I have not be aware of or it is some kind of Python bug?

I tested it on CPython 3.5

Pax0r
  • 2,324
  • 2
  • 31
  • 49
  • Why are you creating *"a module-level variable with `__`"*? – jonrsharpe Nov 30 '16 at 08:03
  • 1
    Note specifically, as quoted from the docs *"This mangling is done without regard to the syntactic position of the identifier"* – jonrsharpe Nov 30 '16 at 08:05
  • Actually one of mine students (I teaching python on some beginner level) did this and I was not sure why it haven't work for him. – Pax0r Nov 30 '16 at 08:06

1 Answers1

4

Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the 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 occurs within the definition of a class.

(from the Python documentation, emphasis mine)

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
abukaj
  • 2,582
  • 1
  • 22
  • 45
  • aww I should checked docs first :P – Pax0r Nov 30 '16 at 08:57
  • see: https://bugs.python.org/issue27793 I'd argue this is a bug, seeing one would reasonably expect that when using the `global` keyword explicitly, one would get the global variable. Even if it's documented its highly inconsistent and illogical. – con-f-use Mar 04 '20 at 22:10
  • @con-f-use It is philosophical question, whether a bug in specification is a bug. ;) I agree that there may be a better way to avoid name clash with subclasses. – abukaj Mar 05 '20 at 20:22
  • My issue is not really with a name clash but with `global` being the stronger "philosophical" concept because it is explicitly stated here. Also, to my knowledge there is no mention in the documentation of global about working everywhere **except** inside classes for variable names staring (but not ending) with `__`... – con-f-use Mar 06 '20 at 21:05
  • @con-f-use What I meant is that the sole purpose of name mangling I can see is to avoid name clashes in subclasses. – abukaj Mar 12 '20 at 16:19