Python方法覆盖,签名是否重要?

时间:2011-05-17 17:23:10

标签: python inheritance methods override

让我说我有

class Super():
  def method1():
    pass

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

这是对的吗?对method1的调用总是会转到子类吗?我的计划是让2个子类重写方法1,使用不同的参数

6 个答案:

答案 0 :(得分:33)

Python会允许这样做,但如果method1()打算从外部代码执行,那么您可能需要重新考虑这一点,因为它违反了LSP,因此无法始终正常运行。

答案 1 :(得分:6)

Python允许使用具有不同签名的“覆盖”方法,但是即使它们的签名不同(即,没有方法重载),也不能在同一类中拥有两个具有相同名称的方法。在覆盖方法的情况下,如果调用的方法为该对象定义的参数数量错误,则会出现错误。记住,Python的方法只是字典中附加到对象上的键-值对,“覆盖”等于简单地替换最初从基类字典复制的相同键的字典中的值。

在许多情况下,您希望派生类方法比基本类具有 additional 参数。要在Python中同时保留LSP,可以使用以下技术:

visit_test

以上将打印:

class Base:
    def hello(self, name, *kargs, **kwargs):
        print("Hello", name)

class Derived(Base):
      def hello(self, name, age=None, *kargs, **kwargs):
          super(Derived, self).hello(name, age, *kargs, **kwargs) 
          print('Your age is ', age)

b = Base()
d = Derived()

b.hello('Alice')
b.hello('Bob', age=24)
d.hello('Rick')
d.hello('John', age=30)

Play with this code

答案 2 :(得分:1)

在python中,所有类方法都是“虚拟的”(就C ++而言)。因此,对于您的代码,如果您想在超类中调用method1(),则必须是:

class Super():
    def method1(self):
        pass

class Sub(Super):
    def method1(self, param1, param2, param3):
       super(Sub, self).method1() # a proxy object, see http://docs.python.org/library/functions.html#super
       pass

方法签名很重要。你不能调用这样的方法:

sub = Sub()
sub.method1() 

答案 3 :(得分:1)

它会起作用:

>>> class Foo(object):
...   def Bar(self):
...     print 'Foo'
...   def Baz(self):
...     self.Bar()
... 
>>> class Foo2(Foo):
...   def Bar(self):
...     print 'Foo2'
... 
>>> foo = Foo()
>>> foo.Baz()
Foo
>>> 
>>> foo2 = Foo2()
>>> foo2.Baz()
Foo2

但是,通常不建议这样做。看一下S.Lott的回答:Methods with the same name and different arguments are a code smell

答案 4 :(得分:1)

如果可以使用默认参数,你可以这样做:

>>> class Super():
...   def method1(self):
...     print("Super")
...
>>> class Sub(Super):
...   def method1(self, param1="X"):
...     super(Sub, self).method1()
...     print("Sub" + param1)
...
>>> sup = Super()
>>> sub = Sub()
>>> sup.method1()
Super
>>> sub.method1()
Super
SubX

答案 5 :(得分:-2)

是。对“method1”的调用将始终转到子类。 Python中的方法签名只包含名称而不是参数列表。