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.

Était-ce utile?

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top