如何才能将类中的属性进行彻底的封装,只允许实例按照规定的方法进行访问呢?
相当于是创建了一个接口,只有通过接口才能访问或修改或添加属性,而其他方式都是被禁止的,让内部的属性私有化。
想达到这样的目的,应该如何设定类呢?
我按照这两天搜索的结果来看,目前最满足需求的设定是这样的:
1类中的属性变量名双下划线开头
2__slots__方法规定不许添加新属性
3__setattr__方法规定不允许修改属性值
但是,我后来也了解到,双下划线开头的变量名仍旧可以直接访问,只要在双下划线前面加上下划线类名,比如b._A__a,就可以绕过__a的隐藏而直接修改,这样看来就不是彻底安全的封装了。
slots方法很好,没有问题。
而__setattr__的问题更多,先是他只能防止赋值运算,对于列表的append防不住,然后是他的防止不仅对实例从外部直接修改属性有效,而且对实例内部方法修改属性也有效,这样就没法实现接口了。
总之实现的不是很理想。
所以想请问有什么比较好的办法可以解决这个问题吗?
相当于是创建了一个接口,只有通过接口才能访问或修改或添加属性,而其他方式都是被禁止的,让内部的属性私有化。
想达到这样的目的,应该如何设定类呢?
我按照这两天搜索的结果来看,目前最满足需求的设定是这样的:
1类中的属性变量名双下划线开头
2__slots__方法规定不许添加新属性
3__setattr__方法规定不允许修改属性值
但是,我后来也了解到,双下划线开头的变量名仍旧可以直接访问,只要在双下划线前面加上下划线类名,比如b._A__a,就可以绕过__a的隐藏而直接修改,这样看来就不是彻底安全的封装了。
slots方法很好,没有问题。
而__setattr__的问题更多,先是他只能防止赋值运算,对于列表的append防不住,然后是他的防止不仅对实例从外部直接修改属性有效,而且对实例内部方法修改属性也有效,这样就没法实现接口了。
总之实现的不是很理想。
所以想请问有什么比较好的办法可以解决这个问题吗?