python私有变量和类本地引用,只能从对像内部访问的“私有”实例变量,在 Python 中不存在。然而,也有一个变通的访问用于大多数 Python 代码:以一个下划线开头的命名(例如 _spam
)会被处理为 API 的非公开部分(无论它是一个函数、方法或数据成员)。它会被视为一个实现细节,无需公开。
因为有一个正当的类私有成员用途(即避免子类里定义的命名与之冲突),Python 提供了对这种结构的有限支持,称为 name mangling (命名编码) 。任何形如 __spam
的标识(前面至少两个下划线,后面至多一个),被替代为 _classname__spam
,去掉前导下划线的 classname
即当前的类名。此语法不关注标识的位置,只要求在类定义内。
名称重整是有助于子类重写方法,而不会打破组内的方法调用。例如:
class Mapping: def __init__(self, iterable): self.items_list = [] self.__update(iterable) def update(self, iterable): for item in iterable: self.items_list.append(item) __update = update # private copy of original update() method class MappingSubclass(Mapping): def update(self, keys, values): # provides new signature for update() # but does not break __init__() for item in zip(keys, values): self.items_list.append(item)
需要注意的是编码规则设计为尽可能的避免冲突,被认作为私有的变量仍然有可能被访问或修改。在特定的场合它也是有用的,比如调试的时候。
要注意的是代码传入 exec
, eval()
或 execfile()
时不考虑所调用的类的类名,视其为当前类,这类似于 global
语句的效应,已经按字节编译的部分也有同样的限制。这也同样作用于 getattr()
, setattr()
和 delattr()
,像直接引用 __dict__
一样。