Python方法覆盖,签名重要吗?

标签 python inheritance methods overriding

假设我有

class Super():
  def method1():
    pass

class Sub(Super):
  def method1(param1, param2, param3):
      stuff

这是正确的吗?对method1的调用是否总是转到子类?我的计划是有 2 个子类,每个子类都使用不同的参数覆盖 method1

最佳答案

在 Python 中,方法只是附加到类的字典中的键值对。当您从基类派生类时,您实际上是在说方法名称将在第一个派生类字典中查找,然后在基类字典中查找。为了“覆盖”一个方法,您只需在派生类中重新声明该方法即可。

那么,如果你改变派生类中被覆盖方法的签名呢?如果在派生实例上调用一切正常,但如果在基实例上进行调用,则会收到错误消息,因为基类对同一方法名称使用不同的签名。

然而,在某些情况下,您希望派生类方法具有 附加 参数,并且您希望方法调用在基础上也能正常工作。这被称为“Liskov 替换原则”(或 LSP),它保证如果人们从基础实例切换到派生实例,反之亦然,他们不必修改他们的代码。要在 Python 中执行此操作,您需要使用以下技术设计基类:

class Base:
    # simply allow additional args in base class
    def hello(self, name, *args, **kwargs):
        print("Hello", name)

class Derived(Base):
      # derived class also has unused optional args so people can
      # derive new class from this class as well while maintaining LSP
      def hello(self, name, age=None, *args, **kwargs):
          super(Derived, self).hello(name, age, *args, **kwargs) 
          print('Your age is ', age)

b = Base()
d = Derived()

b.hello('Alice')        # works on base, without additional params
b.hello('Bob', age=24)  # works on base, with additional params
d.hello('Rick')         # works on derived, without additional params
d.hello('John', age=30) # works on derived, with additional params

上面将打印:

    Hello Alice
    Hello Bob
    Hello Rick
    Your age is  None
    Hello John
    Your age is  30
. Play with this code

关于Python方法覆盖,签名重要吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6034662/

相关文章:

python - 将基类转换为派生类python(或扩展类的更多pythonic方式)

objective-c - 是否可以使用 Objective-C 运行时特性来确定从何处调用方法?

c# - 如何在 C# 中编写超时方法

python - Django:如何发布应用程序

python - 使用 NumPy 和 Pillow 绘制 Mandelbrot 时,程序输出明显的噪声

python - 将 txt 文件中的值列表转换为字典

python - django-tables2 : Table subclassing and Meta inner class attributes

python - 将 GEO 数据库与普通数据库分离

c - 如何使用 C 对继承建模?

java - java打印相同行和数组的方法问题