Quel est le nom de ** en python?

59

Lorsque je programme Python, je fais parfois **une conversion. Je comprends ce qu’il fait, mais quelles structures de données est-ce que je manipule? A dictet quel est l'autre? Un array? Y a-t-il un nom pour l' **opérateur?

Niklas Rosencrantz
la source
3
opérateur exponentiel?
Rook
12
Il y a deux significations pour **. Power et "dictionnaire d'arguments de mots clés". De quoi parlez-vous? La documentation contient les mots suivants: "Si le formulaire“ ** identificateur ”est présent, il est initialisé dans un nouveau dictionnaire recevant les arguments de mot clé en excès, avec par défaut un nouveau dictionnaire vide." Lesquels d’entre eux semblent pertinents à votre question?
S.Lott
"dictionnaire d'argumentaire de mot clé" était celui que je demande. Merci pour les commentaires.
Niklas Rosencrantz le

Réponses:

86

Ce n'est pas un opérateur en tant que tel, donc il n'a pas vraiment de nom, mais il est défini comme une "règle syntaxique" . Donc, il devrait s'appeler:

  • "la syntaxe de décompression de l'argument clé"

Si vous avez une liste d'arguments, *argson l'appelle "décompression d'argument" , de la même manière **kwargson l'appelle "décompression d'argument de mot clé" .

Si vous l'utilisez sur le côté gauche d'un =, comme dans a, *middle, end = my_tuple, vous diriez "déballage des tuples" .

Au total, il existe trois types d'arguments (paramètre unique):

def f(x)  # x: positional argument
def f(x, y=0)  # y: keyword argument
def f(x, *xs, y=0)  # y: keyword-only argument

L' *argsargument est appelé "paramètre de position variable" et **kwargsest le "paramètre de mot clé variable". Les arguments ne contenant que des mots-clés ne peuvent pas être donnés positionnellement, car un paramètre de position variable prendra tous les arguments que vous transmettez.

La plupart de ces informations se trouvent dans les PEP 0362 et 3102 , ainsi que dans la section Flux de contrôle de la documentation. Il convient toutefois de noter que l'objet de signature de fonction PEP n'est qu'un brouillon et que la terminologie peut n'être que l'idée d'une personne. Mais ce sont de bonnes conditions quand même. :)

Ainsi, les arguments *et **ne font que décompresser leurs structures de données respectives:

args = (1, 2, 3)  # usually a tuple, always an iterable[1]

f(*args)  f(1, 2, 3)

# and 

kwargs = {"a": 1, "b": 2, "c": 3}  # usually a dict, always a mapping*

f(**kwargs) -> f(a=1, b=2, c=3)

[1]: Iterables sont des objets qui implémentent la __iter__()méthode et les mappages sont des objets qui implémentent keys()et __getitem__(). Tout objet prenant en charge ce protocole sera compris par les constructeurs tuple()et dict()pourra donc être utilisé pour décompresser les arguments.

Stefano Palazzo
la source
3
Au cas où quelqu'un d'autre serait confus, la def f(x, *xs, y=0): passsyntaxe {5,6,7} de Python 2 n'est pas valide, ni ne def f(x, y=0, *xs):fait ce que vous pourriez attendre. Autant que je sache, le seul moyen d’obtenir l’effet (évidemment) recherché est def f(x, *xs, **kw): y=kw.get('y', 0); del kw; .... Python 3 gère la syntaxe d'origine comme prévu.
Chbrown
1
Tant que nous y sommes: la begin, *middle, end = (0, 1, 2, 3, 4, 5)syntaxe ne fonctionne pas non plus dans Python 2.x.
Stefano Palazzo
Cette réponse est incorrecte dans Python 3.5 et versions ultérieures. PEP-448 spécifie l'opérateur ** en tant qu'opérateur de décompression de dictionnaire. Voir python.org/dev/peps/pep-0448
devnul3
13

Je ne pense pas qu'il a un nom. Dans les documents Python sous "Unpacking Argument Lists", il est simplement appelé "l' **opérateur".

Je ne suis pas sûr de ce que vous entendez par "l'autre" structure de données. Lorsque vous f(**kwargs)décompressez le dictionnaire en kwargstant que séquence de paires clé-valeur. Je ne vois pas qu'il y a une autre structure impliquée.

Je vais copier l' exemple de la documentation ci-dessus pour plus de clarté.

>>> def parrot(voltage, state='a stiff', action='voom'):
...     print "-- This parrot wouldn't", action,
...     print "if you put", voltage, "volts through it.",
...     print "E's", state, "!"
...
>>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
>>> parrot(**d)
-- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !

Voir aussi: Que signifient * args et ** kwargs?

Kris Harper
la source
Un lecteur peut interpréter plusieurs manières possibles f(**kwargs)...
Deer Hunter
3

Si vous ne savez pas comment appeler un opérateur particulier ou s'il n'a pas été nommé, vous pouvez toujours recourir à Waka Waka Bang Splat comme référence pour vous aider à comprendre comment l'appeler. Dans ce cas, **je l'appellerais double-splat, bien qu'il existe d' autres noms pour les symboles .

aculich
la source