python - python中的子类方法重写

标签 python overriding subclass

我写了一段python的测试代码:

class Parent(object):
    @classmethod
    def dispatch(klass):
        print 'klass = %s' % klass
        return klass().__dispatch()
    def __dispatch(self):
        print 'This Parent.__dispatch()'
        print self


class Child(Parent):
    def __dispatch(self):
        print 'This Child.__dispatch()'
        print self


if __name__=='__main__':
    print 'Calling Parent.dispatch() ...\n'
    Parent.dispatch()
    print ''
    print 'Calling Child.dispatch() ...\n'
    Child.dispatch()
    print '\n-END'

输出是:

 Calling Parent.dispatch() ...

 klass = <class '__main__.Parent'> 
 This Parent.__dispatch()
 <__main__.Parent object at 0x0000000002D3A2E8>

 Calling Child.dispatch() ...

 klass = <class '__main__.Child'> 
 This Parent.__dispatch()
 <__main__.Child object at 0x0000000002D3A2E8>

 -END

很奇怪为什么没有调用Child类的重写方法'__dispatch(self)'。

谁能解释一下?

谢谢。

最佳答案

以双下划线开头的方法名会被自动破坏;在内部,字符串 _ClassName 被添加到方法名称之前:

>>> class Foo(object):
...     def __bar(self):
...         pass
... 
>>> Foo.__dict__.keys()
['__dict__', '__module__', '__weakref__', '__doc__', '_Foo__bar']

此重命名也适用于在类中的任何其他方法中引用此方法名称的任何内容。

因此,您的 __dispatch() 方法重命名为 _Parent__dispatch(),并且 dispatch() 方法改变 改为调用 self._Parent__dispatch()。同样,您的 Child 类有一个 _Child__dispatch() 方法,因此它不会覆盖它的父类(super class)的 _Parent__dispatch() 方法-类

这就是您看到结果的原因;将您的 __dispatch() 方法重命名为 _dispatch()(只有一个下划线),它将按预期工作。

python为什么要这样做?它是提供私有(private)属性和方法的一种形式,不会被从它们继承的类意外覆盖。参见 private name mangling在 Python 表达式引用中。

PEP 8 Python Style Guide关于私有(private)名称修改有这样的说法:

If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores. This invokes Python's name mangling algorithm, where the name of the class is mangled into the attribute name. This helps avoid attribute name collisions should subclasses inadvertently contain attributes with the same name.

Note 1: Note that only the simple class name is used in the mangled name, so if a subclass chooses both the same class name and attribute name, you can still get name collisions.

Note 2: Name mangling can make certain uses, such as debugging and __getattr__(), less convenient. However the name mangling algorithm is well documented and easy to perform manually.

Note 3: Not everyone likes name mangling. Try to balance the need to avoid accidental name clashes with potential use by advanced callers.

关于python - python中的子类方法重写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12437941/

相关文章:

java - 类不是抽象的,不会覆盖父类(super class)中的抽象方法

html - 如何删除内联 CSS 元素样式(不使用 JavaScript)?

javascript - 在 JavaScript 中覆盖 console.log

python - 为什么这个 Python 3 asyncio 客户端仅在 Python 进程中断后才发送字节?

python - python根据索引值或列中的值进行查询

dynamic - swift : Parse subclass dynamic var dont get included when retrieving object

java - 如何防止子类继承父类(super class)中的静态方法

python - 子类化 tk.Listbox 时出错(属性错误对象没有属性 'tk' )

python - 有没有办法在类内的装饰器中引用实例?

python - Numpy:如何基于子矩阵 B 返回矩阵 A 的 View