6.11 给模块的私有属性上保险¶
保护对象¶
有的朋友,喜欢简单粗暴的使用 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 *
时,由解释器提供简单的保护,但是可以轻易突破。这种保护更多地依赖程序员的共识:不访问、修改“保护属性”。除此之外,有没有更安全的保护机制呢?有,就是下一部分讨论的私有变量。