Python: Как получить доступ к объекту родительского класса через экземпляр производного класса? - PullRequest
5 голосов
/ 15 февраля 2010

Извините за мой глупый вопрос, но ... предположим, у меня есть эти классы:

class A():
    msg = 'hehehe'

class B(A):
    msg = 'hohoho'

class C(B):
    pass

и экземпляр B или C. Как я могу получить переменную 'msg' из родительского объекта класса через этот экземпляр? Я пробовал это:

foo = B()
print super(foo.__class__).msg

но получил сообщение: «TypeError: super () аргумент 1 должен быть типом, а не classobj».

Ответы [ 6 ]

15 голосов
/ 15 февраля 2010

Вы действительно хотите использовать

class A(object):
    ...
...
b = B()
bar = super(b.__class__, b)
print bar.msg

Базовые классы должны быть классами нового стиля (наследовать от object)

8 голосов
/ 15 февраля 2010

Если класс унаследован:

foo = B()
print foo.__class__.__bases__[0].msg
# 'hehehe'

Если класс наследуется несколькими способами, этот вопрос не имеет смысла, поскольку могут существовать несколько классов, определяющих «msg», и все они могут иметь смысл. Вам лучше указать фактического родителя (т.е. A.msg). В качестве альтернативы вы можете выполнить итерацию по всем прямым базам, как описано в ответе @ Felix .

2 голосов
/ 15 февраля 2010

Не уверен, почему вы хотите это сделать

>>> class A(object):
...     msg = 'hehehe'
... 
>>> class B(A):
...     msg = 'hohoho'
... 
>>> foo=B()
>>> foo.__class__.__mro__[1].msg
'hehehe'
>>> 
1 голос
/ 15 февраля 2010

Поскольку msg является переменной класса, вы можете просто сделать:

print C.msg    # prints hohoho

Если вы перезаписываете переменную (как в классе B), вы должны найти правильный родительский класс. Помните, что Python поддерживает множественное наследование .

Но так как вы определили классы и теперь, когда B наследует от A, вы всегда можете сделать это:

class B(A):
    msg = 'hohoho'

    def get_parent_message(self):
       return A.msg

UPDATE:

Самая надежная вещь будет:

def get_parent_attribute(instance, attribute):
    for parent in instance.__class__.__bases__:
        if attribute in parent.__dict__:
             return parent.__dict__[attribute]

и затем:

foo = B()
print get_parent_attribute(foo, 'msg')
1 голос
/ 15 февраля 2010

Попробуйте с:

class A(object):
    msg = 'hehehe'

EDIT:

Для атрибута msg вам понадобится:

foo = B()
bar = super(foo.__class__, foo)
print bar.msg
0 голосов
/ 15 февраля 2010
#for B() you can use __bases__
print foo.__class__.__bases__[0].msg

Но это будет нелегко, если есть несколько базовых классов и / или глубина иерархии не одна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...