Итак, когда вы вызываете конструктор для Developer (создаете новый экземпляр), функция __init__(self,first, last, pay, prog_lang)
вызывается неявно.
Если мы посмотрим на конструктор:
def __init__(self,first, last, pay, prog_lang):
super().__init__(first,last,pay)
self.prog_lang = prog_lang
мы видим, что конструктор суперкласса вызывается во второй строке. Это, в свою очередь, устанавливает переменные-члены для экземпляра, на которые позже будут ссылаться при построении полного имени:
def fullname(self):
fullname = self.first + ' ' + self.last
return print(fullname)
В более широком смысле язык отслеживает, какие переменные привязаны к какому классу и python в частности дает программисту довольно большую свободу, когда дело доходит до объема и типов. Если вы хотите узнать больше об этом топе c, я бы порекомендовал W3 C s python tutorial и, в частности, Тип безопасности и Наследование