对名称混淆目的的总结是否正确?

  • 本文关键字:是否 python oop name-mangling
  • 更新时间 :
  • 英文 :


From docs:

由于存在类私有成员的有效用例(即避免名称与子类定义的名称冲突),因此对这种称为名称mangling的机制的支持有限。任何形式为__spam的标识符(至少两个前导下划线,最多一个尾下划线)在文本上被替换为_classname__spam,其中classname是去掉前导下划线的当前类名。只要在类的定义中出现,这种混淆就不会考虑标识符的语法位置。

我的解释:

  1. 修改父类方法parent.__m(a, b)的名称,以允许子类用额外的参数child.m(a, b, c)重载它。这样,当你调用child.m(1, 2, 3)时,额外的参数就不会传递给父类,从而混淆它。

  2. 如果您计划保持相同的方法签名,但更改一些内部功能,则不需要修改。您仍然可以通过使用super()来访问旧的功能。

  3. 总之,如果你希望将来能够重载一个类方法,那就把它弄乱。否则,就没有必要了。

问题:

我的总结正确吗?文档写得很差。大量的连续句和中游(旁白),使我无法确定自己是否理解正确。

编辑:我只是玩了一些代码:

class Parent( object ):
def __init__(self, a, b):
self.a = a
self.b = b

def method( self ):
return 1
class Child(Parent):
def __init__(self, a, b, c ):
super().__init__(a, b)
def method(self, c):
field = [c]
return field

a, b, c = 0, 1, 2
c = Child(a, b, c)
print(c)

这个工作得很好。我遇到的唯一问题是,如果我这样做:

class Parent( object ):
def __init__(self, a, b):
self.a = a
self.b = b
self.c = self.method()

def method( self ):
return 1
class Child(Parent):
def __init__(self, a, b, c ):
super().__init__(a, b)
self.c = self.method(c)
def method(self, c):
field = [c]
return field

a, b, c = 0, 1, 2
c = Child(a, b, c)

返回

TypeError: method() missing 1 required positional argument: 'c'

这在以下回答中讨论:Python,重写继承的类方法

所以在一天结束的时候,看起来我仍然不明白目的是什么。

对于子类重写具有更多参数的方法来说,名称混淆是不必要的。目的是防止重写方法,特别是重写"private"方法。

为类的内部目的服务且其行为不应被子类更改的方法。这个想法是,如果一个子类声明了一个"相同"的方法。名称时,它将被修改为不同的名称,以避免重写超类的方法。与Java相比,private方法不能被重写,甚至不能从子类中调用

class A:
def foo(self):
self.bar()
self.__baz()
def bar(self):
print('A.bar')
def __baz(self):
print('A.__baz')
class B(A):
def bar(self):
print('B.bar')
def __baz(self):
print('B.__baz')
B().foo()

输出:

B.bar
A.__baz
注意这是关于重写,而不是重载。Python没有方法重载,方法调用中参数的数量或类型不用于确定调用哪个方法;只使用方法名。

最新更新