There is limited support for class-private
identifiers. Any identifier of the form __spam
(at least two
leading underscores, at most one trailing underscore) is now textually
replaced with _classname__spam
, where classname
is the
current class name with leading underscore(s) stripped. This mangling
is done without regard of the syntactic position of the identifier, so
it can be used to define class-private instance and class variables,
methods, as well as globals, and even to store instance variables
private to this class on instances of other classes. Truncation
may occur when the mangled name would be longer than 255 characters.
Outside classes, or when the class name consists of only underscores,
no mangling occurs.
Python 对类的私有成员提供了有限的支持。任何形如
__spam
(以至少双下划线开头,至多单下划线结尾)随即都被替代为
_classname__spam
,去掉前导下划线的classname
即当前的类名。这种混淆不关心标识符的语法位置,所以可用来定义私有类实例和类变量、方法,以及全局变量,甚至于将其它类的实例保存为私有变量。混淆名长度超过255个字符的时候可能会发生截断。在类的外部,或类名只包含下划线时,不会发生截断。
Name mangling is intended to give classes an easy way to define ``private'' instance variables and methods, without having to worry about instance variables defined by derived classes, or mucking with instance variables by code outside the class. Note that the mangling rules are designed mostly to avoid accidents; it still is possible for a determined soul to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger, and that's one reason why this loophole is not closed. (Buglet: derivation of a class with the same name as the base class makes use of private variables of the base class possible.)
命名混淆意在给出一个在类中定义“私有”实例变量和方法的简单途径,避免派生类的实例变量定义产生问题,或者与外界代码中的变量搞混。要注意的是混淆规则主要目的在于避免意外错误,被认作为私有的变量仍然有可能被访问或修改。在特定的场合它也是有用的,比如调试的时候,这也是一直没有堵上这个漏洞的原因之一(小漏洞:派生类和基类取相同的名字就可以使用基类的私有变量。)
Notice that code passed to exec
, eval()
or
evalfile()
does not consider the classname of the invoking
class to be the current class; this is similar to the effect of the
global
statement, the effect of which is likewise restricted to
code that is byte-compiled together. The same restriction applies to
getattr()
, setattr()
and delattr()
, as well as
when referencing __dict__
directly.
要注意的是传入 exec
,eval()
或 evalfile()
的代码不会将调用它们的类视作当前类,这与 global
语句的情况类似,global
的作用局限于“同一批”进行字节编译的代码。同样的限制也适用于
getattr()
,setattr()
和
delattr()
,以及直接引用 __dict__
的时候。