如何从 class 访问 Python 模块的私有变量
How to access private variable of Python module from class
在 Python 3 中,在 class 变量前加上前缀使其成为私有的,我在 class 中修改名称。如何访问 class 中的模块变量?
比如下面两种方式都不行:
__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}
[为了易读性添加了换行符]
运行 模块(与解释器相对)中的相同代码导致完全相同的行为。使用 Anaconda 的 Python 3.5.1 :: Continuum Analytics, Inc.
.
您正在通过传递未定义的变量来实例化 class。将 __a 放在 class 之外将不起作用,因为 class 将看不到此变量。你应该做的是:
__a = 3
class B:
def __init__(self, __a):
self.a = __a
b = B(__a)
这样你就可以在构造函数中传递一个参数来进行初始化。
如果您打算像您尝试的那样破坏名称,那么我建议您阅读这篇文章: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`
这样,您也可以更具体地了解正在调用的变量,而无需为以后修改它留出太多空间。希望这有效。
它很难看,但你可以访问全局变量:
__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()
显然 "official" 答案是不要在 class 之外使用双下划线。这在此处的文档中暗示:https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references. Furthermore, the following (failed) bug report (and this response) 使其明确。
在 Python 3 中,在 class 变量前加上前缀使其成为私有的,我在 class 中修改名称。如何访问 class 中的模块变量?
比如下面两种方式都不行:
__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}
[为了易读性添加了换行符]
运行 模块(与解释器相对)中的相同代码导致完全相同的行为。使用 Anaconda 的 Python 3.5.1 :: Continuum Analytics, Inc.
.
您正在通过传递未定义的变量来实例化 class。将 __a 放在 class 之外将不起作用,因为 class 将看不到此变量。你应该做的是:
__a = 3
class B:
def __init__(self, __a):
self.a = __a
b = B(__a)
这样你就可以在构造函数中传递一个参数来进行初始化。
如果您打算像您尝试的那样破坏名称,那么我建议您阅读这篇文章: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`
这样,您也可以更具体地了解正在调用的变量,而无需为以后修改它留出太多空间。希望这有效。
它很难看,但你可以访问全局变量:
__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()
显然 "official" 答案是不要在 class 之外使用双下划线。这在此处的文档中暗示:https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references. Furthermore, the following (failed) bug report (and this response) 使其明确。