2017-02-21 14 views
1

Пусть класс А наследуется от B и B наследуется от C.Как получить доступ к предку объекта в питон

class C(): 
    def my_method(self): 
     pass 

class B(C): 
    def my_method(self): 
     pass 

class A(B): 
    def my_method(self): 
     # Call my_method from B 
     super(A, self).my_method() 
     # How can I call my_method from C here ? 

Вопрос: Как я могу позвонить my_method из C?

+0

Вы имеете в виду родительский класс 'SomeClass'? – Dschoni

+0

Звучит как [XY-проблема] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Как правило, вам не нужно обращаться к конкретным предкам, просто дайте 'супер' выяснить, к кому обращаться, в этом весь смысл [« MRO »(порядок разрешения метода)] (https://www.python.org/download /releases/2.3/mro/). – MSeifert

+0

Обратите внимание, что существует только один объект, созданный 'A()'. Этот объект является экземпляром всех его суперклассов, но для родительских классов не создаются индивидуальные объекты. – kazemakase

ответ

1

Вы можете вызвать my_method() метод C «s просто вызовом„несвязанного“метод непосредственно, с self передается в качестве аргумента. Например:

class C(object): 
    def my_method(self): 
     print('C.my_method') 

class B(C): 
    def my_method(self): 
     print('B.my_method') 

class A(B): 
    def my_method(self): 
     print('A.my_method') 
     super(A, self).my_method() # calls B.my_method(self) 
     C.my_method(self)   # calls C.my_method(self) 

a = A() 
a.my_method() 

При запуске, что напечатает следующее (обратите внимание на (object) требуется для super() работать на Python 2.x):

A.my_method 
B.my_method 
C.my_method 

Однако, как уже отмечалось, это не лучший способ добиться того, чего вы хотите. Можете ли вы привести конкретный пример того, чего вы пытаетесь достичь в контексте?

+0

На самом деле я хочу переопределить my_method в классе A, другими словами, я собираюсь добавить некоторые функции для my_method класса C, а не класса B. –

0

Вы можете получить доступ к полной родословной объекта, используя его атрибут __mro__:

In [3]: KeyError.__mro__ 
Out[3]: (KeyError, LookupError, StandardError, Exception, BaseException, object) 
0

Прежде всего, если вы хотите использовать супер функцию, то вы должны использовать базовый класс как объект, как этого

class c(object): 
    pass 

Потому что супер поддержку функции только в новом программировании стиля только питон.

Теперь переход к функции базового класса базового класса. В вашем случае как вызвать функцию my_method класса C от A.

Вы можете сделать это двумя способами статически и динамически.

Динамически

class C(object): 
    def my_method(self): 
     print "in function c" 

class B(C): 
    def my_method(self): 
     print "in function b" 

class A(B): 
    def my_method(self): 
     # Call my_method from B 
     super(A, self).my_method() 
     # This is how you can call my_method from C here ? 
     super((self.__class__.__bases__)[0], self).my_method() 
obj_a = A() 
obj_a.my_method() 

Здесь (self.__class__.__bases__) возвращает базовые классы А в Thats типа кортежей, почему я взял 0-й индекс. Таким образом, он возвращает класс B, имея класс B в качестве аргумента в супер, он вернет функцию my_method базового класса класса b.

Статически

class C(object): 
    def my_method(self): 
     print "in function c" 

class B(C): 
    def my_method(self): 
     print "in function b" 

class A(B): 
    def my_method(self): 
     # Call my_method from B 
     super(A, self).my_method() 
     # This is how you can call my_method from C here ? 
obj_a = A() 
super(A,obj_a).my_method() # calls function of class B 
super(B,obj_a).my_method() # calls function of class A