如何在 python 中覆盖父类的函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2484215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I override a parent class's functions in python?
提问by wrongusername
I have a private method def __pickSide(self):
in a parent class that I would like to override in the child class. However, the child class still calls the inherited def __pickSide(self):
. How can I override the function? The child class's function name is exactly the same as the parent's function name.
我def __pickSide(self):
在父类中有一个私有方法,我想在子类中覆盖它。但是,子类仍然调用继承的def __pickSide(self):
. 如何覆盖该功能?子类的函数名与父类的函数名完全相同。
回答by AndiDog
Let's look at the easiest example:
让我们看一个最简单的例子:
from dis import dis
class A(object):
def __pick(self):
print "1"
def doitinA(self):
self.__pick()
class B(A):
def __pick(self):
print "2"
def doitinB(self):
self.__pick()
b = B()
b.doitinA() # prints 1
b.doitinB() # prints 2
dis(A.doitinA)
print
dis(B.doitinB)
The disassembly is as follows:
拆解如下:
8 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (_A__pick)
6 CALL_FUNCTION 0
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
15 0 LOAD_FAST 0 (self)
3 LOAD_ATTR 0 (_B__pick)
6 CALL_FUNCTION 0
9 POP_TOP
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
As you can see, Python mangles function names that begin with two underscores (and accesses to such names!!) to a name that includes the class name - in this case _A__pick
and _B__pick
). That means that the class in which a function is defined determines which of the __pick
methods is called.
如您所见,Python 会将以两个下划线开头的函数名称(以及对此类名称的访问!!)修改为包含类名称的名称 - 在本例中为_A__pick
和_B__pick
)。这意味着定义函数的类决定__pick
调用哪个方法。
The solution is simple, avoid pseudo-private methods by removing the double underscores. For example, use _pick
instead of __pick
.
解决方案很简单,通过删除双下划线来避免伪私有方法。例如,使用_pick
代替__pick
。
回答by Ignacio Vazquez-Abrams
The problem you're seeing is that the double underscores mangle the function name even in calls. This prevents polymorphism from working properly since the name it is mangled to is based on the name of the class the method is defined in, and not the name of the class of the object that is being referenced. Replacing the double underscores with something else will solve this.
您看到的问题是,即使在调用中,双下划线也会破坏函数名称。这会阻止多态性正常工作,因为它被修改的名称基于定义方法的类的名称,而不是被引用的对象的类的名称。用其他东西替换双下划线将解决这个问题。
回答by Mike Graham
Using
__foo
names mangles the name of the method to make it more hassle to access it when you need to. I would recommend never using them, which makes things like testing go more smoothly.There is no private in Python, and if there was, it would prevent you from doing this anyhow. (This is the point of private stuff in languages that have it.)
The common convention to indicate that an attribute is not part of the public interface of a class it to use a single leading underscore, like
_foo
. This is sufficient for making your code clear separating your internal details from your public API.
使用
__foo
名称会破坏方法的名称,以便在需要时更轻松地访问它。我建议永远不要使用它们,这会让测试之类的事情进行得更顺利。Python 中没有私有,如果有,无论如何它都会阻止你这样做。(这是拥有它的语言中私有内容的重点。)
指示属性不是类的公共接口的一部分的通用约定使用单个前导下划线,如
_foo
. 这足以使您的代码清晰地将您的内部细节与您的公共 API 分开。