Python 方法覆盖,签名重要吗? [英] Python Method overriding, does signature matter?

查看:21
本文介绍了Python 方法覆盖,签名重要吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有

class Super():定义方法1():经过类子(超级):def 方法 1(param1, param2, param3):东西

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

解决方案

在 Python 中,方法只是附加到类的字典中的键值对.当您从基类派生类时,您实际上是在说方法名称将首先查看派生类字典,然后查看基类字典.为了覆盖"一个方法,您只需在派生类中重新声明该方法.

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

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

类基础:# 只允许在基类中添加额外的参数def hello(self, name, *args, **kwargs):打印(你好",姓名)派生类(基类):# 派生类也有未使用的可选参数,所以人们可以# 从这个类派生新类,同时保持 LSPdef hello(self, name, age=None, *args, **kwargs):super(Derived, self).hello(name, age, *args, **kwargs)print('你的年龄是', age)b = 基数()d = 派生()b.hello('Alice') # 在基础上工作,没有额外的参数b.hello('Bob', age=24) # 在基础上工作,有额外的参数d.hello('Rick') # 适用于派生,无需额外参数d.hello('John', age=30) # 处理派生的,有额外的参数

上面会打印:<前>你好爱丽丝你好鲍勃你好瑞克你的年龄没有你好约翰你的年龄是 30

.玩这个代码

Lets say I have

class Super():
  def method1():
    pass

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

Is this correct? Will calls to method1 always go to the sub class? My plan is to have 2 sub classes each override method1 with different params

解决方案

In Python, methods are just key-value pairs in the dictionary attached to the class. When you are deriving a class from a base class, you are essentially saying that method name will be looked into first derived class dictionary and then in the base class dictionary. In order to "override" a method, you simply re-declare the method in the derived class.

So, what if you change the signature of the overridden method in the derived class? Everything works correctly if the call is on the derived instance but if you make the call on the base instance, you will get an error because the base class uses a different signature for that same method name.

There are however frequent scenarios where you want derived class method have additional parameters and you want method call work without error on base as well. This is called "Liskov substitution principle" (or LSP) which guarantees that if person switches from base to derived instance or vice versa, they don't have to revamp their code. To do this in Python, you need to design your base class with the following technique:

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

Above will print:

    Hello Alice
    Hello Bob
    Hello Rick
    Your age is  None
    Hello John
    Your age is  30

. Play with this code

这篇关于Python 方法覆盖,签名重要吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆