2010-04-25 6 views
7

Ai-je raté quelque chose ici? Pourquoi le code sous la section "Broken" ne devrait-il pas fonctionner? J'utilise Python 2.6.Erreur de syntaxe étrange dans Python?

#!/usr/bin/env python 

def func(a,b,c): 
    print a,b,c 

#Working: Example #1: 

p={'c':3} 

func(1, 
    b=2, 
    c=3, 
    ) 

#Working: Example #2: 

func(1, 
    b=2, 
    **p) 

#Broken: Example #3: 

func(1, 
    b=2, 
    **p, 
    ) 
+2

Lorsque j'essaye ce code sous Python 2.6, j'obtiens une erreur de syntaxe à la ligne 19 (la deuxième Working). –

+0

Merci, correction d'une faute de frappe mineure dans l'exemple # 2. – user213060

+1

Et (non sans importance): pourquoi voudriez-vous cette virgule (sauf pour la recherche de ce comportement)? – ChristopheD

Répondre

9

Ceci est le bit correspondant du grammar:

arglist: (argument ',')* (argument [','] 
         |'*' test (',' argument)* [',' '**' test] 
         |'**' test) 

La première ligne ici permet de mettre une virgule après le dernier paramètre lorsque vous n'utilisez varargs/kwargs (ce qui est la raison pour laquelle votre premier exemple fonctionne) . Cependant, vous n'êtes pas autorisé à placer une virgule après le paramètre kwargs s'il est spécifié, comme indiqué dans les deuxième et troisième lignes.

D'ailleurs, voici une chose intéressante montre la grammaire:

Ce sont à la fois juridique:

f(a=1, b=2, c=3,) 
f(*v, a=1, b=2, c=3) 

mais ce n'est pas:

f(*v, a=1, b=2, c=3,) 

Il est logique de ne pour autoriser une virgule après **kwargs, car il doit toujours être le dernier paramètre. Je ne sais pas pourquoi les concepteurs de la langue ont choisi de ne pas autoriser mon dernier exemple - peut-être un oubli?

5

Python autorise généralement des virgules supplémentaires à la fin des virgules (dans les listes d'arguments et les littéraux de conteneur). L'objectif principal est de rendre la génération de code légèrement plus facile (vous n'avez pas besoin de caser le dernier élément ou double-cas particulier d'un tuple singleton).

Dans la définition de la grammaire, **kwargs est extrait séparément et sans une virgule facultative supplémentaire. Cela ne m'aiderait jamais avec quelque chose de pratique comme la génération de code (** kwargs sera toujours la dernière chose pour que vous n'ayez rien de spécial) autant que je puisse l'imaginer, donc je ne sais pas pourquoi Python supporterait il.