13.14 私有化
1. 双下划线(__)
>>> class C(object):
... __attr = 0
...
>>> print C.__attr
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: type object 'C' has no attribute '__attr'
>>> print C().__attr
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
AttributeError: 'C' object has no attribute '__attr'
>>> class C(object):
... attr = 0
...
>>> print C.attr
0
>>>
Python为类元素(属性和方法)的私有性提供初步的形式。由双下划线开始的属性在运行时被"混淆",所以直接访问是不允许的。
2. 单下划线(_)
简单的模块级私有化只需要在属性名前使用一个单下划线字符。这是严格基于作用域的,所以这同样适用于函数。
13.15 *授权
当引用一个属性时,Python解释器将试着在局部名称空间中查找那个名字,比如一个自定义的方法或者局部实例属性。如果没有在局部字典中找到,则搜索类名称空间,以防一个类属性被访问。最后,如果两类搜索都失败了,搜索则对原对象开始授权要求,此时__getattr__()会被调用。
>>> class WrapMe(object):
... def __init__(self, obj):
... self.__data = obj
... def get(self):
... return self.__data
... def __repr__(self):
... return `self.__data`
... def __str__(self):
... return str(self.__data)
... def __getattr__(self,attr):
... return getattr(self.__data, attr)
...
>>> complex = WrapMe(1.1)
>>> complex
1.1
>>> print complex
1.1
>>> dir(complex)
['_WrapMe__data', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'get']
>>> complex.__class__
<class '__main__.WrapMe'>
>>>
对这些属性的访问,是通过getattr()方法,授权给对象。