Здесь так много вопросов. Я вижу как минимум два, может, три:
- Что делает pop (a, b)? / Почему есть второй аргумент?
- Для
*argsчего используется?
На первый вопрос тривиальный ответ дан в справочнике по стандартной библиотеке Python :
pop (клавиша [, по умолчанию])
Если ключ находится в словаре, удалите его и верните его значение, иначе верните значение по умолчанию. Если значение по умолчанию не указано и ключ отсутствует в словаре, возникает ошибка KeyError.
Второй вопрос рассматривается в Справочнике по языку Python :
Если присутствует форма «* идентификатор», она инициализируется кортежем, получающим любые избыточные позиционные параметры, по умолчанию - пустой кортеж. Если присутствует форма «** идентификатор», она инициализируется новым словарем, получающим любые избыточные аргументы ключевого слова, по умолчанию используется новый пустой словарь.
Другими словами, popфункция принимает как минимум два аргумента. Первым двум присваиваются имена selfи key; а остальные помещаются в кортеж с именем args.
То, что происходит в следующей строке, когда *argsпередается в вызове, self.data.popявляется обратным этому - кортеж *argsрасширяется до позиционных параметров, которые передаются. Это объясняется в Справочнике по языку Python :
Если в вызове функции появляется синтаксис * выражение, выражение должно оцениваться как последовательность. Элементы из этой последовательности обрабатываются, как если бы они были дополнительными позиционными аргументами
Короче говоря, он a.pop()хочет быть гибким и принимать любое количество позиционных параметров, чтобы он мог передать это неизвестное количество позиционных параметров self.data.pop().
Это дает вам гибкость; dataоказывается dictпрямо сейчас и поэтому self.data.pop()принимает один или два параметра; но если вы изменили dataтип, который принимает 19 параметров для вызова, self.data.pop()вам вообще не придется менять класс a. Однако вам все равно придется изменить любой код, который вызывается a.pop()для передачи необходимых 19 параметров.
help(b.data.pop)в REPL.