6.11 给模块的私有属性上保险

http://image.iswbm.com/20200804124133.png

保护对象

有的朋友,喜欢简单粗暴的使用 from x import * 来导入 x 模块中的所有对象,实际上有一些对象或者变量,是实现细节,不需要暴露给导入方的,因为导入了也用不上。

对于这些变量或者对象,就可以在前面其名字前加上下划线,只要在变量名前加上下划线,就属于 “保护对象”。

使用 from x import * 后,这些 “保护对象” 是会直接跳过导入。

比如下面这些代码中,只有 drive 函数才会被 from x import * 所导入

_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没有提供解释器机制来控制访问权限。我们依然可以访问这些属性:

import tools
tools._moto_type = 'EA211'
tools.drive()

以上代码,以越过“保护属性”。此外,还有两种方法能突破这个限制,一种是将“私有属性”添加到tool.py文件的__all__列表里,使from tools import *也导入这些本该隐藏的属性。

__all__ = ['drive','_moto_type','_wheel_type']

另一种是导入时指定“受保护属性”名。

from tools import drive,_start_engine
_start_engine()

甚至是,使用import tools也可以轻易突破保护限制。所以可见,“保护属性”是一种简单的隐藏机制,只有在from tools import *时,由解释器提供简单的保护,但是可以轻易突破。这种保护更多地依赖程序员的共识:不访问、修改“保护属性”。除此之外,有没有更安全的保护机制呢?有,就是下一部分讨论的私有变量。