在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.
。
答案 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`
通过这种方式,您对所调用的变量也更加具体,没有太多空间可以在以后进行修改。希望这有效。