variables - 在 Python 中访问类的**私有**变量
问题描述
我知道 Python 没有明确支持类中的私有变量。但是,请考虑以下程序:
class AClass(object):
def __init__(self, x):
self.__x = x
class BClass(object):
def __init__(self, x):
self.__x = x
# _____________________________________________________________________________
aClass = AClass(10)
bClass = BClass(10)
aClass.__x = 15
print (aClass.__x)
##bClass.__x = 20
print (bClass.__x)
上面的程序,会产生如下错误: AttributeError: 'BClass' object has no attribute '__x'
但是,如果代码的倒数第二行未注释,它将执行而不会出错。
如果有人可以澄清似乎不一致的地方,并且如果有一个 PEP 可以解释这种行为,我将不胜感激。
此致。
BD
解决方案
这是因为以 dunder 开头的变量名称被修改以“保护”它们。如果您检查 的字典bClass
,您会看到:
>>> print(bClass.__dict__)
{'_BClass__x': 10, '__x': 20}
(我将其_BClass__x
称为对象变量)是由对象本身创建的,因此它的名称不正确。__x
是在类(a)之外创建的,这就是它具有未损坏名称的原因,因此您可以使用.__x
要访问这两种类型的对象变量,您可以使用:
print (aClass._AClass__x)
print (bClass._BClass__x)
但我不确定这有多可靠。我确信这是你可能不应该做的事情,因为它破坏了封装:-)
事实上,虽然我说重整是由对象完成的,但我想确保您理解它不是在实例化对象时完成的。编译代码时会发生实际的修改,如果您反汇编,您可以看到:
>>> import dis
>>> dis.dis(AClass)
Disassembly of __init__:
3 0 LOAD_FAST 1 (x)
2 LOAD_FAST 0 (self)
4 STORE_ATTR 0 (_AClass__x)
6 LOAD_CONST 0 (None)
8 RETURN_VALUE
字节码实际上知道使用错误的STORE_ATTR
名称。
(a)它与对象变量非常不同,当您稍后尝试__x
在成员函数中使用并发现它没有被您的外部代码更改时,您会发现您的痛苦:-)
推荐阅读
- types - 在 SML 中,产品类型和函数类型是类型构造函数吗?
- reactjs - 基于外部数据的样式 Mapbox GL 矢量图层
- c++ - QCursor 设置光标颜色的问题
- regex - RegEX 从 shell 脚本中的字符串中获取必填字段
- python - Python input().split() 函数问题
- hyperledger-fabric - Tx 提交后获取空缓冲区:Fabric 2.1 with fabric-network client
- node.js - 与多个连接一起使用时,Mongoose 不会在 .find() 中返回记录
- python - 在python中将基于图像的pdf转换为图像文件(png/jpg)
- python - Python将日期时间转换为另一种格式
- spring - Axon - 调用后的 MessageHandlerInterceptor / 处理程序