这个名称修改目的的总结是否正确?
Is this summary of the purpose of name mangling correct?
来自文档:
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.
我的解读:
修改父 class 方法的名称 parent.__m(a, b)
以允许子级使用额外参数重载它 child.m(a, b, c)
。这样当你调用 child.m(1, 2, 3)
时,额外的参数不会被传递给父 class 并混淆它。
如果您计划保留相同的方法签名但更改某些内部功能,则不需要进行重整。您仍然可以使用 super()
.
访问旧功能
总而言之,如果您希望将来能够重载 class 方法,请破坏它。否则没必要。
问题:
我的总结正确吗?文档写得不好。大量 运行-on 句子和中流(旁白)混淆了我确定我是否理解正确的能力。
编辑: 我刚刚玩了一些代码:
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)
哪个returns
TypeError: method() missing 1 required positional argument: 'c'
这在这个答案中讨论:Python, Overriding an inherited class method
所以到头来我好像还是不明白目的是什么。
子 class 不需要名称重整来覆盖具有更多参数的方法。目的是 防止 重写方法,特别是重写“私有”方法,该方法为 class 服务于某些内部目的,其行为不应被 sub 更改classes.
想法是,如果子class 声明了一个“相同”名称的方法,它将被分解为不同的方法,以避免覆盖超class 的方法。与 Java 进行比较和对比,其中 private
方法无法被覆盖,甚至无法从子 class.
中 调用
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 没有方法重载,方法调用中参数的数量或类型不用于确定调用哪个方法;仅使用方法名称。
来自文档:
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.
我的解读:
修改父 class 方法的名称
parent.__m(a, b)
以允许子级使用额外参数重载它child.m(a, b, c)
。这样当你调用child.m(1, 2, 3)
时,额外的参数不会被传递给父 class 并混淆它。如果您计划保留相同的方法签名但更改某些内部功能,则不需要进行重整。您仍然可以使用
访问旧功能super()
.总而言之,如果您希望将来能够重载 class 方法,请破坏它。否则没必要。
问题:
我的总结正确吗?文档写得不好。大量 运行-on 句子和中流(旁白)混淆了我确定我是否理解正确的能力。
编辑: 我刚刚玩了一些代码:
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)
哪个returns
TypeError: method() missing 1 required positional argument: 'c'
这在这个答案中讨论:Python, Overriding an inherited class method
所以到头来我好像还是不明白目的是什么。
子 class 不需要名称重整来覆盖具有更多参数的方法。目的是 防止 重写方法,特别是重写“私有”方法,该方法为 class 服务于某些内部目的,其行为不应被 sub 更改classes.
想法是,如果子class 声明了一个“相同”名称的方法,它将被分解为不同的方法,以避免覆盖超class 的方法。与 Java 进行比较和对比,其中 private
方法无法被覆盖,甚至无法从子 class.
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 没有方法重载,方法调用中参数的数量或类型不用于确定调用哪个方法;仅使用方法名称。