Tantas perguntas aqui. Eu vejo pelo menos dois, talvez três:
- O que pop (a, b) faz? / Por que há um segundo argumento?
- Para que está
*argssendo usado?
A primeira pergunta é trivialmente respondida na referência da Biblioteca Padrão do Python :
pop (tecla [, padrão])
Se a chave estiver no dicionário, remova-a e retorne seu valor, caso contrário, retorne o padrão. Se o padrão não for fornecido e a chave não estiver no dicionário, um KeyError é gerado.
A segunda pergunta é abordada na Referência da linguagem Python :
Se a forma “* identificador” estiver presente, ele é inicializado com uma tupla recebendo quaisquer parâmetros posicionais em excesso, assumindo como padrão a tupla vazia. Se a forma “** identificador” estiver presente, ele é inicializado para um novo dicionário recebendo quaisquer argumentos de palavra-chave em excesso, assumindo como padrão um novo dicionário vazio.
Em outras palavras, a popfunção leva pelo menos dois argumentos. Os dois primeiros recebem os nomes selfe key; e o resto é colocado em uma tupla chamada args.
O que acontece na próxima linha quando *argsé transmitido na chamada de self.data.popé o inverso disso - a tupla *argsé expandida para dos parâmetros posicionais que são transmitidos. Isso é explicado na Referência da linguagem Python :
Se a sintaxe * expressão aparecer na chamada de função, a expressão deve ser avaliada como uma sequência. Os elementos desta sequência são tratados como se fossem argumentos posicionais adicionais
Resumindo, a.pop()quer ser flexível e aceitar qualquer número de parâmetros posicionais, de modo que possa passar esse número desconhecido de parâmetros posicionais para self.data.pop().
Isso lhe dá flexibilidade; datapassa a ser um dictagora e, portanto, self.data.pop()leva um ou dois parâmetros; mas se você mudar datapara um tipo que usa 19 parâmetros para uma chamada para, self.data.pop()você não terá que mudar de classe a. Você ainda teria que alterar qualquer código chamado a.pop()para passar os 19 parâmetros necessários.
help(b.data.pop)no REPL.