如何避免不小心弄乱 Python 中的基数 class?
How to avoid accidentally messing up the base class in Python?
Python 对私有变量使用下划线约定。然而,似乎没有什么能阻止你不小心弄乱基数 class,例如
class Derived(Base):
def __init__(self, ...):
...
super(Derived, self).__init__(...)
...
self._x = ...
如果 Base
也恰好使用了名字 _x
。
避免此类错误的最佳做法是什么?
这似乎特别具有挑战性,如果不同的人实施 Base
和 Derived
classes,或者 _x
在 [=16= 之后添加到 Base
=] 已实施(因此,Derived
的实施将追溯性地破坏封装)
使用private variables with two underscores。这样,名称修改可以防止您弄乱 parent class(在正常使用情况下)。
Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.
[...] Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger.
例子
class A(object):
def __init__(self):
self.__v = 1
def __str__(self):
return "A = {}".format(self.__v)
class B(A):
def __init__(self):
A.__init__(self)
self.__v = 2
def __str__(self):
return "{}; B = {}".format(A.__str__(self), self.__v)
a = A()
b = B()
print(a)
print(b)
产量
A = 1
A = 1; B = 2
Python 对私有变量使用下划线约定。然而,似乎没有什么能阻止你不小心弄乱基数 class,例如
class Derived(Base):
def __init__(self, ...):
...
super(Derived, self).__init__(...)
...
self._x = ...
如果 Base
也恰好使用了名字 _x
。
避免此类错误的最佳做法是什么?
这似乎特别具有挑战性,如果不同的人实施 Base
和 Derived
classes,或者 _x
在 [=16= 之后添加到 Base
=] 已实施(因此,Derived
的实施将追溯性地破坏封装)
使用private variables with two underscores。这样,名称修改可以防止您弄乱 parent class(在正常使用情况下)。
Since there is a valid use-case for class-private members (namely to avoid name clashes of names with names defined by subclasses), there is limited support for such a mechanism, called name mangling. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with leading underscore(s) stripped. This mangling is done without regard to the syntactic position of the identifier, as long as it occurs within the definition of a class.
[...] Note that the mangling rules are designed mostly to avoid accidents; it still is possible to access or modify a variable that is considered private. This can even be useful in special circumstances, such as in the debugger.
例子
class A(object):
def __init__(self):
self.__v = 1
def __str__(self):
return "A = {}".format(self.__v)
class B(A):
def __init__(self):
A.__init__(self)
self.__v = 2
def __str__(self):
return "{}; B = {}".format(A.__str__(self), self.__v)
a = A()
b = B()
print(a)
print(b)
产量
A = 1
A = 1; B = 2