Quel est le but de l'astérisque nu dans les arguments de fonction ?
-
21-12-2019 - |
Question
J'ai vu cette question SO (ce n'est pas un doublon) : Python nu astérisque dans l'argument de la fonction
Dans python-3.x, vous pouvez ajouter un nu *
aux arguments de la fonction, cela signifie que (citation de documents):
Les paramètres après «*» ou «* identificateur» sont des paramètres de mot-clé uniquement et peuvent être adoptés uniquement des arguments de mots clés utilisés.
Ok, j'ai défini une fonction :
>>> def f(a, b, *, c=1, d=2, e=3):
... print('Hello, world!')
...
je peux passer c
, d
et e
valeurs des variables uniquement en spécifiant des mots-clés :
>>> f(1, 2, 10, 20, 30)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 5 were given
>>> f(1, 2, c=10, d=20, e=30)
Hello, world!
Les questions sont :
- Quelle est la motivation de ce type de sucre de restriction/syntaxe ?
- Quels cas d’utilisation couvre-t-il ?
- Est-il vraiment utilisé dans les bibliothèques tierces passées à python3 ?
Quelques exemples du « monde réel » seraient très utiles.Merci d'avance.
La solution
PEP 3102 explique la justification assez clairement :le but est de permettre aux fonctions d'accepter diverses "options" qui sont essentiellement de nature orthogonale.Les spécifier positionnellement est délicat à la fois du côté de la définition et du côté appelant, car ils n'ont pas de "priorité" évidente qui se traduirait par un ordre de position.
Il existe de nombreux exemples de fonctions qui pourraient en bénéficier dans diverses bibliothèques.Par exemple, la signature d'appel de pandas.read_csv
est:
def parser_f(filepath_or_buffer,
sep=sep,
dialect=None,
compression=None,
doublequote=True,
escapechar=None,
quotechar='"',
quoting=csv.QUOTE_MINIMAL,
skipinitialspace=False,
lineterminator=None,
header='infer',
index_col=None,
names=None,
prefix=None,
skiprows=None,
skipfooter=None,
skip_footer=0,
na_values=None,
na_fvalues=None,
true_values=None,
false_values=None,
delimiter=None,
converters=None,
dtype=None,
usecols=None,
engine='c',
delim_whitespace=False,
as_recarray=False,
na_filter=True,
compact_ints=False,
use_unsigned=False,
low_memory=_c_parser_defaults['low_memory'],
buffer_lines=None,
warn_bad_lines=True,
error_bad_lines=True,
keep_default_na=True,
thousands=None,
comment=None,
decimal=b'.',
parse_dates=False,
keep_date_col=False,
dayfirst=False,
date_parser=None,
memory_map=False,
nrows=None,
iterator=False,
chunksize=None,
verbose=False,
encoding=None,
squeeze=False,
mangle_dupe_cols=True,
tupleize_cols=False,
infer_datetime_format=False):
À l'exception du chemin du fichier, la plupart d'entre elles sont des options orthogonales qui spécifient différents aspects de la façon dont un fichier CSV doit être analysé.Il n’y a aucune raison particulière pour laquelle ils seraient adoptés dans un ordre particulier.Vous deviendrez fou en gardant une trace de n'importe quel ordre de position pour ceux-ci.Il est plus logique de les transmettre sous forme de mots-clés.
Maintenant, vous pouvez voir que pandas ne les définit pas réellement comme arguments de mots-clés uniquement, probablement pour maintenir la compatibilité avec Python 2.J'imagine que de nombreuses bibliothèques se sont abstenues d'utiliser la syntaxe pour la même raison.Je ne sais pas quelles bibliothèques (le cas échéant) ont commencé à l'utiliser.
Autres conseils
Pour ceux qui viennent de ou/et ont utilisé ruby
Ci-dessous l'expression en python
def f(a, b, *, c=1, d=2, e=3):
est similaire à
def f(a,b, options={})
c = options[:c] || 1
d = options[:d] || 2
e = options[:e] || 3
end
en rubis.
Puisque python est explicite vaut mieux qu’implicite langue, cela nécessite *
(éclaboussure) opérateur dans les paramètres.
PS :Je n'ai jamais utilisé Python, si je me trompe, corrigez-moi.