从python类引用外部作用域

时间:2016-09-08 18:37:47

标签: python class python-3.x module scope

我有一个(简化的)模块,如下所示:

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

2 个答案:

答案 0 :(得分:3)

你看到有效的名字毁了。来自documentation

  

__spam形式的任何标识符(至少两个前导下划线,最多一个尾随下划线)在文本上替换为_classname__spam,其中classname是当前类名,前导下划线被剥离。 完成此修改不考虑标识符的句法位置,只要它出现在类的定义中。

据我所知,解决这个问题的唯一方法是将全局范围内的__outerVar重命名为不以双下划线开头的内容。

答案 1 :(得分:3)

Python会替换任何前面带有双下划线__的名称,以便模拟私有属性&#39;。实质上__name变为_classname__name。这称为名称修改,仅在记录in the docs

的类中发生
  

这种修改完成时不考虑标识符的句法位置,只要它出现在类的定义中。

解决方案是不使用__name名称,使用_namename就足够了。

作为附录,在PEP 8 -- Method Names and Instance Variables中声明:

  

Python使用类名来破坏这些名称:如果类Foo具有名为__a的属性,则Foo.__a无法访问它。 (坚持不懈的用户仍然可以通过调用Foo._Foo__a获得访问权限。)通常,双重前导下划线应该仅用于避免与设计为子类的类中的属性发生名称冲突。

因此,除非您为案例设计子类名称冲突可能会出现问题,否则请不要使用双引号下划线。