Python - ordem de descompactação de valor nos parâmetros do método

8
def fun(a, b, c, d):
    print('a:', a, 'b:', b, 'c:', c, 'd:', d)

por que esse funciona

fun(3, 7, d=10, *(23,))

e imprime:

a: 3 b: 7 c: 23 d: 10

enquanto isso

fun(3, 7, c=10, *(23,))

não

Traceback (most recent call last):
  File "/home/lookash/PycharmProjects/PythonLearning/learning.py", line 10, in <module>
    fun(3, 7, c=10, *(23,))
TypeError: fun() got multiple values for argument 'c'
Łukasz
fonte
Não sei o motivo exato pelo qual o erro foi gerado, mas você nunca deve ter argumentos variáveis ​​após argumentos de palavra-chave. Normalmente, um erro é gerado, mas a descompactação da tupla parece gerar um erro diferente do normal SyntaxError: positional argument follows keyword argument.
Erro - Remorso sintático
@ Error-SyntacticalRemorse. Eu acho que você está perdendo o ponto. O OP encontrou um caso em que você pode realmente colocar uma posição após uma palavra-chave e funciona.
Mad Físico
@ MadPhysicist eu vejo isso. Mas eu estava apenas afirmando que a descompactação da tupla não deveria ocorrer após os argumentos das palavras-chave. Assim, eu fiz isso como um comentário, não como uma resposta.
Erro - Remorso sintático
1
Pergunta incrível. Nunca soube que isso era uma coisa.
Erro - Remorso sintático

Respostas:

6

Com *(23,), você está descompactando os valores na tupla (23,)como argumentos posicionais, seguindo os argumentos posicionais já definidos, ou seja, 3para ae 7para b, por isso 23seriam atribuídos ao parâmetro c, e é por isso que fun(3, 7, d=10, *(23,))funciona, mas fun(3, 7, c=10, *(23,))você também está atribuindo valor 10ac como um argumento de palavra-chave, portanto, é considerado um conflito, pois cnão pode ser atribuído com ambos 23e10 .

Observe que, embora legal, é desencorajado por alguns descompactar argumentos iteráveis ​​após argumentos de palavra-chave, conforme discutido aqui , embora a sintaxe seja finalmente mantida.

blhsing
fonte
Está claro o que está acontecendo, mas desde quando você pode descompactar posições após palavras-chave?
Mad Físico
Desde Python 3.
blhsing 20/11/19
Você tem uma fonte para isso? É intencional e documentado, ou possivelmente um bug / omissão?
Mad Físico
A descompactação da tupla deve ocorrer antes dos argumentos da palavra-chave em termos de ordem de operação. Pode ser uma omissão ...
Erro - Remorso sintático
1
@MadPhysicist My bad. Eu estava pensando em outra coisa. Essa sintaxe também é legal no Python 2. O caso de uso primário, como é evidente no caso de teste CPython f(1,2,c=3,*d,**e)em test_ast.py , é permitir que uma função de wrapper passe argumentos variáveis ​​e argumentos de palavra-chave para a função de forma mais intuitiva, colocando os argumentos e a palavra-chave variável. argumentos no final da lista de argumentos.
blhsing 20/11/19