我有一个(简化的)模块,如下所示:
import tkinter as tk
__outerVar = {<dict stuff>}
class Editor(tk.Frame):
...
def _insideFunction(self):
for p in __outerVar.keys():
<do stuff>
当我尝试实例化编辑器时,我正在使用NameError: name '_Editor__outerVar' is not defined
获得__outerVar
。我试过把&#34; global __outerVar
&#34;在insideFunction
的顶部,即使我没有写__outerVar
,也是同样的错误。
我确定我在这里误解了一些python范围规则。帮助
py 3.5
答案 0 :(得分:3)
你看到有效的名字毁了。来自documentation:
__spam
形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam
,其中classname是当前类名,前导下划线被剥离。 完成此修改不考虑标识符的句法位置,只要它出现在类的定义中。
据我所知,解决这个问题的唯一方法是将全局范围内的__outerVar
重命名为不以双下划线开头的内容。
答案 1 :(得分:3)
Python会替换任何前面带有双下划线__
的名称,以便模拟私有属性&#39;。实质上__name
变为_classname__name
。这称为名称修改,仅在记录in the docs:
这种修改完成时不考虑标识符的句法位置,只要它出现在类的定义中。
解决方案是不使用__name
名称,使用_name
或name
就足够了。
作为附录,在PEP 8 -- Method Names and Instance Variables
中声明:
Python使用类名来破坏这些名称:如果类
Foo
具有名为__a
的属性,则Foo.__a
无法访问它。 (坚持不懈的用户仍然可以通过调用Foo._Foo__a
获得访问权限。)通常,双重前导下划线应该仅用于避免与设计为子类的类中的属性发生名称冲突。
因此,除非您为案例设计子类名称冲突可能会出现问题,否则请不要使用双引号下划线。