问题
封装类的实例的“私有”数据,但是Python语言并没有访问控制。
解决方案
Python程序员不是依赖语言特性去封装数据,而是通过遵循一定的属性和方法命名规范,来达到这个效果。
任何以单下划线(_)
开头的名字都应该是内部属性。比如:
class A(object):
def __init__(self):
self._internal = 0 # An internal attribute
self.public = 1 # A public attribute
def public_method(self):
pass
def _internal_method(self):
pass
Python并不会真的阻止别人访问内部名称(属性)。使用下划线开头的命名规范同样适用于模块名和模块级别函数。
使用双下划线(__)
开头的名字,也都是内部属性,且会导致访问名称变成其他形式,比如:
class B(object):
def __init__(self):
self.__private = 0
def __private_method(self):
pass
def public_method(self):
pass
self.__private_method()
示例中,访问双下划线(__)
开头的私有属性时,会被分别重命名为 _B__private
和 _B__private_method
。其目的就是类继承时,这些私有的属性或方法不会被覆盖。
讨论
单双下划线开头的属性和方法命名规范,都是用来命名私有属性,通常情况下,非公共名称以单下划线开头进行命名,如果考虑代码会涉及到子类时,并且有些内部属性应该在子类中隐藏起来,那么才考虑使用双下划线开头的命名方式。
有时候,定义一个变量时,考虑可能与某个保留关键字冲突,可以使用单下划线作为后缀,例如:
lambda_ = 2.0 # Trailing _ to avoid clash with lambda keyword
这里并不使用单下划线前缀的原因,是避免误解它的使用初衷,被理解为这个属性是私有的。
网友评论