如何从类访问Python模块的私有变量

时间:2016-01-05 21:24:47

标签: python python-3.x scope name-mangling

在Python 3中,为类变量添加前缀会使其变为私有,从而破坏了类中的名称。如何访问类中的模块变量?

例如,以下两种方法不起作用:

__a = 3
class B:
    def __init__(self):
        self.a = __a
b = B()

结果:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in __init__
NameError: name '_B__a' is not defined

使用global也无济于事:

__a = 3
class B:
    def __init__(self):
        global __a
        self.a = __a
b = B()

结果:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in __init__
NameError: name '_B__a' is not defined

正在运行locals()表示变量__a存在未编辑的内容:

>>> locals()
{'__package__': None, '__name__': '__main__',
 '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
 '__doc__': None, '__a': 3, 'B': <class '__main__.B'>,
 '__builtins__': <module 'builtins' (built-in)>, '__spec__': None}

[Newlines为易读性添加]

在模块中运行相同的代码(而不是解释器)会导致完全相同的行为。使用Anaconda&#39; Python 3.5.1 :: Continuum Analytics, Inc.

4 个答案:

答案 0 :(得分:1)

它很难看,但你可以访问全局:

__a = 3
class B:
    def __init__(self):
        self.a = globals()["__a"]
b = B()

你也可以把它放在一个字典中:

__a = 3

d = {"__a": __a}

class B:
    def __init__(self):
        self.a = d["__a"]
b = B()

或列表,元组等..和索引:

__a = 3

l = [__a]

class B:
    def __init__(self):
        self.a = l[0]
b = B()

答案 1 :(得分:1)

显然,“官方”答案不是在课堂外使用双下划线。这在以下文档中暗示:https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references。此外,以下(失败的)bug report(和this response)使其明确。

答案 2 :(得分:-2)

您通过传递未定义的变量来实例化一个类。将__a放在类外面不会起作用,因为类不会看到这个变量。你应该做的是:

__a = 3
class B:
def __init__(self, __a):
   self.a = __a
b = B(__a)

这样你就可以在构造函数中传递一个参数来进行初始化。

答案 3 :(得分:-2)

如果你要按照你想要的方式破坏名字,那么我会推荐你​​参考这篇文章:http://shahriar.svbtle.com/underscores-in-python

因此,我对你要做的事情的解决方案如下:`

class R:
    global _R__a
    _R__a = 3
    def __init__(self):
        pass

class B:    
    global _R__a    
    def __init__(self):     
        self.a = _R__a
b = B()
print b.a
#3`

通过这种方式,您对所调用的变量也更加具体,没有太多空间可以在以后进行修改。希望这有效。

相关问题