Python与下划线(三)名称改写机制避免冲突
在Python中,双下划线(__
)前缀的变量名和方法名会触发名称改写(name mangling)机制,这是Python为了避免子类与父类之间的命名冲突而设计的一种特性。名称改写机制会将类中的双下划线前缀的变量名或方法名改写为_ClassName__variableName
或_ClassName__methodName
的形式,其中ClassName
是定义该变量或方法的类的名称。
名称改写机制的工作原理
当你在一个类中定义了一个双下划线前缀的属性或方法时,Python解释器会在内部将其名称改写为包含类名的形式。这样做的目的是确保当子类继承了父类,并且子类中也定义了相同名称的双下划线属性或方法时,它们不会相互冲突。
示例
以下是一个简单的示例,展示了名称改写机制是如何工作的:
class Parent:
__private_var = "I am from Parent"
def __init__(self):
self.__init_var = "Initialized in Parent"
def show_vars(self):
print(self.__private_var)
print(self.__init_var)
class Child(Parent):
__private_var = "I am from Child"
def __init__(self):
super().__init__()
self.__init_var = "Initialized in Child"
def show_parent_vars(self):
# 尝试访问父类的私有变量,由于名称改写,这里访问的是子类自己的变量
print(self.__private_var) # 输出: I am from Child
# 要访问父类的私有变量,需要使用改写后的名称
print(self._Parent__private_var) # 输出: I am from Parent
# 创建子类实例
child = Child()
child.show_parent_vars()
# 尝试直接调用父类的方法,该方法会访问其自己的私有变量
child.show_vars() # 输出:
# I am from Parent
# Initialized in Parent
在上面的示例中,Parent
类定义了两个双下划线前缀的变量:__private_var
和__init_var
。当Child
类继承Parent
类时,它尝试定义自己的__private_var
变量。由于名称改写机制,Child
类中的__private_var
实际上被改写为_Child__private_var
,因此它与Parent
类中的__private_var
(被改写为_Parent__private_var
)是不同的变量。
使用场景
名称改写机制主要用于以下场景:
-
避免子类与父类之间的命名冲突:当子类需要定义与父类同名的属性或方法时,可以使用双下划线前缀来避免冲突。
-
实现私有属性或方法的封装:虽然Python没有真正的私有属性或方法(因为总是可以通过名称改写后的形式访问),但双下划线前缀通常被视为一种约定,表明这些属性或方法是“私有”的,不应该被外部直接访问。
注意事项
_ClassName__variableName
或_ClassName__methodName
的形式(其中ClassName
是父类的名称),但这通常被视为一种不推荐的做法。作者:软件技术NINI