2017-02-20 4 views
0

В принципе, проблема у меня спрашивает here и есть некоторые ответы, как показано ниже, где Son делают некоторые вещи, как Father (инициализации в данном случае) и некоторые другие вещи, как GrandFather (do_thing).Вызов метода родителя-родителя, какие-либо последствия?

class GrandFather(object): 
    def __init__(self): 
     pass 

    def do_thing(self): 
     # stuff 

class Father(GrandFather): 
    def __init__(self): 
     super(Father, self).__init__() 

    def do_thing(self): 
     # stuff different than Grandfather stuff 

class Son(Father): 
    def __init__(self): 
     super(Son, self).__init__() 

    def do_thing(self): 
     super(Father, self).do_thing() # <-- this line bypasses Father's implementation 

Что я интересно, если есть какие-либо последствия для вызова super подобное (последняя строка выше), то есть, передавая тип класса, кроме ваших собственных. Я имею в виду что-то вроде вашего кода, разбивающегося в какой-то странной точке, где вы этого не ожидаете.

+0

Что еще не покрыто [здесь] (http://stackoverflow.com/questions/5033903/python-super-method-and-calling-alternatives), [здесь] (http://stackoverflow.com/questions/222877/what-do-super-do-in-python) или [здесь] (http://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods)? –

+1

@StephenRauch, что не покрыто? Мой вопрос не распространяется! : D Обратите внимание, что последняя строка в моем примере читает 'super (Father, self)', а не 'super (Son, self)'. Последний является обычным способом использования 'super', и это описано в ссылках, которые вы предоставили. Мой вопрос, однако, о первом, где я обходит прямой родительский класс и называю метод в классе grandparent! – Mahdi

ответ

0

О чем вы спрашиваете, как правило, работает, но он может не делать именно то, что вы намереваетесь при наличии множественного наследования. Например, если Son унаследовал от Mother класса (который из-за кровосмешения был также подкласс Grandfather), вы не получите вызов вы ожидали от последней строки:

class GrandFather(object): 
    def do_thing(self): 
     print("Grandfather") 

class Father(GrandFather): 
    def do_thing(self): 
     print("Father") 

class Mother(GrandFather): 
    def do_thing(self): 
     print("Mother") 

class Son(Father, Mother): 
    def do_thing(self): 
     super(Father, self).do_thing() # will print "Mother", not "Grandfather" 

Эта проблема может даже растениеводстве неожиданно, если множественное наследование было добавлено в подкласс Son (например, class GrandSon(Son, Mother): pass с вашим предыдущим определением Son, наследующим только от Father).

Это может быть или не быть тем, что вы хотите. Если вы хотите получить GrandFather в исполнении do_thing все время, вы должны явно позвонить GrandFather.do_thing(self), вместо того, чтобы пытаться использовать super.

Но, как правило, не рекомендуется проводить классы в обход методов своих родителей. Вам, вероятно, будет лучше обслуживаться путем реорганизации вашего кода, чтобы он не был необходим. Возможно, вы можете отчислить части GrandFather.do_thing, которые вы хотите Son, чтобы использовать их отдельным методом. Вам не нужно было бы переопределять этот метод в Father, вы могли бы просто не называть его от Father.do_thing.

Смежные вопросы