Подтвердить что ты не робот

Метод Python, переопределяющий, имеет подпись?

Скажем, у меня

class Super():
  def method1():
    pass

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

Это правильно? Будет ли вызов метода1 всегда переходить к подклассу? Мой план состоит в том, чтобы иметь 2 под класса каждый метод переопределения1 с разными параметрами

4b9b3361

Ответ 1

Python разрешит это, но если method1() предназначен для выполнения из внешнего кода, вам может потребоваться пересмотреть это, поскольку он нарушает LSP и поэтому выиграл Всегда работайте правильно.

Ответ 2

В python все методы класса являются "виртуальными" (с точки зрения С++). Итак, в случае вашего кода, если вы хотите называть 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

Он будет работать:

>>> 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 ответ: Методы с тем же именем и разными аргументами являются запахом кода.

Ответ 4

Вы можете сделать что-то подобное, если использовать аргументы по умолчанию:

>>> 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

Python разрешает "переопределять" методы с разными сигнатурами, но вы никогда не можете иметь два метода с одинаковыми именами в одном классе, если их сигнатуры различны (т.е. нет перегрузки методов). В случае переопределения метода, Python выдаст ошибку, если вы вызываете методы с неправильными параметрами, которые не определены в объекте. Помните, что методы Python - это просто пары "ключ-значение" в словаре, присоединенном к объекту, и "переопределение" равнозначно простой замене значения в этом словаре, изначально скопированного из словаря базового класса для того же ключа.

Часто существуют сценарии, в которых вы хотите, чтобы метод производного класса имел дополнительные параметры, чем базовый класс. Чтобы сделать это в Python, сохраняя при этом LSP, вы можете использовать следующую технику:

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

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

b = Base()
d = Derived()

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

Выше будет напечатано:

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

Играть с этим кодом

Ответ 6

Да. Звонки на "method1" всегда будут попадать в подкласс. Подпись метода в Python состоит только из имени, а не списка аргументов.