Вопрос-Ответ

How do I call a parent class's method from a child class in Python?

Как мне вызвать метод родительского класса из дочернего класса в Python?

При создании простой иерархии объектов в Python я хотел бы иметь возможность вызывать методы родительского класса из производного класса. В Perl и Java для этого есть ключевое слово (super). В Perl я мог бы сделать это:

package Foo;

sub frotz {
return "Bamf";
}

package Bar;
@ISA = qw(Foo);

sub frotz {
my $str = SUPER::frotz();
return uc($str);
}

В Python кажется, что я должен явно называть родительский класс из дочернего.
В приведенном выше примере мне пришлось бы сделать что-то вроде Foo::frotz().

Это кажется неправильным, поскольку такое поведение затрудняет создание глубоких иерархий. Если дочерним классам нужно знать, какой класс определил унаследованный метод, то возникают всевозможные информационные проблемы.

Это фактическое ограничение в python, пробел в моем понимании или и то, и другое?

Переведено автоматически
Ответ 1

Используйте super() функцию:

class Foo(Bar):
def baz(self, **kwargs):
return super().baz(**kwargs)

Для Python < 3 вы должны явно согласиться на использование классов нового стиля и использовать:

class Foo(Bar):
def baz(self, arg):
return super(Foo, self).baz(arg)
Ответ 2

В Python также есть super:

super(type[, object-or-type])


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


Пример:

class A(object):     # deriving from 'object' declares A as a 'new-style-class'
def foo(self):
print "foo"

class B(A):
def foo(self):
super(B, self).foo() # calls 'A.foo()'

myB = B()
myB.foo()
Ответ 3
ImmediateParentClass.frotz(self)

будет просто отлично, независимо от того, определен ли непосредственный родительский класс frotz сам или унаследовал его. super необходим только для надлежащей поддержки множественного наследования (и тогда он работает только в том случае, если каждый класс использует его должным образом). В общем, AnyClass.whatever будет искать whatever в AnyClassпредках, если AnyClass не определяет / переопределяет его, и это справедливо для "дочернего класса, вызывающего родительский метод", как и для любого другого случая!

Ответ 4

Python 3 имеет другой и более простой синтаксис для вызова родительского метода.

Если Foo класс наследует от Bar, то из Bar.__init__ можно вызвать из Foo через super().__init__():

class Foo(Bar):

def __init__(self, *args, **kwargs):
# invoke Bar.__init__
super().__init__(*args, **kwargs)
python class