Почему меняются местами аргументы при использовании функции super()?

Вопрос формулировал, наверное, двое суток, толком так и не знаю как спросить. Долго и упорно гуглил, но не понял... Есть код. И я пытаюсь разобрать его пошагово. ссылка на PythonTutor Суть в том, что понимаю в какой момент, но не понимаю почему, из-за строки super().__init__(surname, name, position) аргументы "меняются местами" и на выходе вместо Bilbo Baggins получается Baggins Bilbo. Я понимаю причину, происходит это из-за того, что у меня в super().__init__(surname, name, position) surname и name поменяны местами относительно инициализатора дочернего классаdef __init__(self, name, surname, position): Но я не понимаю почему это происходит. Это ведь не именованные аргументы. Я не совсем понимаю очевидно как работает super(). Я полагал, что важен порядок, т.е. в surname super'а подаётся name из def __init__(self, name, surname, position), но он же всё-равно стоит на первом месте...

Дико извиняюсь за такой скомканый вопрос, надеюсь кто-нибудь всё-таки поймёт.

class Worker:
    def __init__(self, name, surname, position):
        self.name = name
        self.surname = surname
        self.position = position
        self._income = {'wage':3000, 'bonus':1000}
        
class Position(Worker):
    def __init__(self, name, surname, position):
        super().__init__(surname, name, position)
        
    def get_full_name(self):
        return '{} {}'.format(self.name, self.surname)
    
    def get_total_income(self):
        return self._income['wage'] + self._income['bonus']
    
    
pos = Position('Bilbo', 'Baggins', 'Treasure Hunter')

print(pos.get_full_name())

Ответы (2 шт):

Автор решения: Pavel Mayorov

В данном случае вызов через super() ничем не отличается от вызова обычной функции, позиционные аргументы передаются абсолютно одинаково при любых вызовах:

def super_init(name, surname):
    print('{} {}'.format(name, surname))

def the_init(name, surname):
    super_init(surname, name)

super_init('Bilbo', 'Baggins') # Bilbo Baggins
the_init  ('Bilbo', 'Baggins') # Baggins Bilbo
→ Ссылка
Автор решения: insolor

В данном случае вы передаете параметры не как именованные, а как позиционные, поэтому нужно передавать параметры именно в том порядке, в каком они у вас перечислены в __init__ родительского класса.

Имена переменных, значения которых вы передаете в __init__ никак не связаны с именами параметров __init__ родительского класса. То есть при вызове super().__init__(surname, name, position) у вас, например, значение переменной surname передается первым параметром, а в __init__ родительского класса первый параметр - name, то есть вместо имени передается фамилия, и т.д.

Если хотите передавать параметры в произвольном порядке, передавайте их как именованные параметры:

super().__init__(surname=surname, name=name, position=position)

Тут слева от равно - имя параметра, справа - имя переменной, значение которой вы передаете.


Еще раз по шагам:

  • pos = Position('Bilbo', 'Baggins', 'Treasure Hunter') - тут вызывается __init__ класса Position (объявление def __init__(self, name, surname, position)), в первый параметр (name) попадает 'Bilbo', во второй (surname) - 'Baggins'
  • super().__init__(surname, name, position) - тут вызывается __init__ класса Worker (объявление def __init__(self, name, surname, position)), в первый параметр (name) вы кладете значение из переменной surname ('Baggins'), во второй (surname) - значение из переменной name ('Bilbo')

Ответ на вопрос "Почему меняются местами аргументы" - потому что вы сами их поменяли местами.

→ Ссылка