Reputation: 3313
I have a (simplified) module, something like this:
import tkinter as tk
__outerVar = {<dict stuff>}
class Editor(tk.Frame):
...
def _insideFunction(self):
for p in __outerVar.keys():
<do stuff>
I'm getting a NameError: name '_Editor__outerVar' is not defined
on the use of __outerVar
when I try to instantiate Editor. I tried putting "global __outerVar
" at the top of insideFunction
, even though I'm not writing to __outerVar
, same error.
I'm sure I'm just misunderstanding some python scope rule here. Help?
py 3.5
Upvotes: 1
Views: 338
Reputation: 160447
Python replaces any names preceded by a double underscore __
in order to simulate 'private attributes'. In essence __name
becomes _classname__name
. This, called name mangling, happens only within classes as documented in the docs:
This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.
The solution is don't use __name
names, using something like _name
or just name
suffices.
As an addendum, in PEP 8 -- Method Names and Instance Variables
it states:
Python mangles these names with the class name: if class
Foo
has an attribute named__a
, it cannot be accessed byFoo.__a
. (An insistent user could still gain access by callingFoo._Foo__a
.) Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.
So, unless you're designing for cases were subclass name clashing might be issue, don't use double leading underscores.
Upvotes: 3
Reputation: 309929
You're seeing name mangling in effect. From the documentation:
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.
As far as I can think, the only way around this is to rename the __outerVar
in the global scope to something that doesn't start with double underscores.
Upvotes: 3