Я пытаюсь вызвать метод суперкласса, используя имя метода переменной. Обычно я вижу следующие две строки кода как эквивалентные:
someObj.method()
someObj.__getattribute__( 'method' )()
И на самом деле я верю, что это именно то, что происходит, когда я использую первую строку. Однако в следующем примере вторая строка вызывает странную проблему.
Я использую super
для создания суперобъекта и вызова метода суперкласса. Выполнение этого напрямую работает, как и ожидалось, но использование __getattribute__
для первого получения метода приводит к неопределенному циклу, который снова и снова вызывает метод подкласса.
См. Следующий код:
class A:
def example ( self ):
print( 'example in A' )
class B ( A ):
def example ( self ):
print( super( B, self ).example )
print( super( B, self ).__getattribute__( 'example' ) )
super( B, self ).example()
#super( B, self ).__getattribute__( 'example' )()
print( 'example in B' )
x = B()
x.example()
Если вы запускаете этот код, все работает, как ожидалось, и вы должны получить вывод, подобный следующему:
<bound method B.example of <__main__.B object at 0x01CF6C90>>
<bound method B.example of <__main__.B object at 0x01CF6C90>>
example in A
example in B
Таким образом, оба метода, один с прямым доступом и один через __getattribute__
, выглядят одинаково. Однако если вы замените вызов метода закомментированной строкой, вы получите ошибку времени выполнения рекурсии.
Почему это происходит, и, что более важно, как я могу получить доступ к методу таким же образом, как это делает Python внутри, когда я использую рабочую строку?
редактировать
Когда я подумал, что уже все перепробовал, я обнаружил, что это работает:
super.__getattribute__( super( B, self ), 'example' )()
Это на самом деле равно super( B, self ).example
.