6.11 给模块的私有属性上保险 =========================== .. image:: http://image.iswbm.com/20200804124133.png 保护对象 -------- 有的朋友,喜欢简单粗暴的使用 ``from x import *`` 来导入 x 模块中的所有对象,实际上有一些对象或者变量,是实现细节,不需要暴露给导入方的,因为导入了也用不上。 对于这些变量或者对象,就可以在前面其名字前加上下划线,只要在变量名前加上下划线,就属于 “保护对象”。 使用 ``from x import *`` 后,这些 “保护对象” 是会直接跳过导入。 比如下面这些代码中,只有 drive 函数才会被 ``from x import *`` 所导入 .. code:: python _moto_type = 'L15b2' _wheel_type = 'michelin' def drive(): _start_engine() _drive_wheel() def _start_engine(): print('start engine %s'%_moto_type) def _drive_wheel(): print('drive wheel %s'%_wheel_type) 突破保护 -------- 前面之所以说是“保护”并不是“私有”,是因为Python没有提供解释器机制来控制访问权限。我们依然可以访问这些属性: .. code:: python import tools tools._moto_type = 'EA211' tools.drive() 以上代码,以越过“保护属性”。此外,还有两种方法能突破这个限制,一种是将“私有属性”添加到tool.py文件的\ ``__all__``\ 列表里,使\ ``from tools import *``\ 也导入这些本该隐藏的属性。 .. code:: python __all__ = ['drive','_moto_type','_wheel_type'] 另一种是导入时指定“受保护属性”名。 .. code:: python from tools import drive,_start_engine _start_engine() 甚至是,使用\ ``import tools``\ 也可以轻易突破保护限制。所以可见,“保护属性”是一种简单的隐藏机制,只有在\ ``from tools import *``\ 时,由解释器提供简单的保护,但是可以轻易突破。这种保护更多地依赖程序员的共识:不访问、修改“保护属性”。除此之外,有没有更安全的保护机制呢?有,就是下一部分讨论的私有变量。