Je voudrais signaler une fonction qui ne fait rien:
def identity(*args)
return args
mon cas d'utilisation est quelque chose comme ça
try:
gettext.find(...)
...
_ = gettext.gettext
else:
_ = identity
Bien sûr, je pourrais utiliser le identity
défini ci-dessus, mais une fonction intégrée serait certainement plus rapide (et éviterait les bugs introduits par moi-même).
Apparemment, map
et filter
utilisent None
pour l'identité, mais cela est spécifique à leurs implémentations.
>>> _=None
>>> _("hello")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable
Pour faire d'autres recherches, il n'y en a pas, une fonctionnalité a été posée dans numéro 16732 Et à partir de Raymond Hettinger a dit qu'il n'y en aura pas :
Mieux vaut laisser les gens écrire leurs propres transitions triviales et réfléchir aux coûts de signature et de temps.
Donc, une meilleure façon de le faire est réellement (un lambda évite de nommer la fonction):
_ = lambda *args: args
OR
_ = lambda x: x
Une fonction d'identité, telle que définie dans https://en.wikipedia.org/wiki/Identity_function , prend un seul argument et le renvoie tel quel:
def identity(x):
return x
Ce que vous demandez lorsque vous dites que vous voulez que la signature def identity(*args)
ne soit pas strictement une fonction d’identité, telle que vous la souhaitez. arguments multiples. Bien, mais vous rencontrez un problème comme Python ne renvoient pas plusieurs résultats. Vous devez donc trouver un moyen de regrouper tous ces arguments dans une seule valeur de retour.
Le moyen habituel de renvoyer des "valeurs multiples" dans Python est de renvoyer un tuple des valeurs - techniquement, il s'agit d'une valeur de retour, mais il peut être utilisé dans la plupart des contextes comme s'il s'agissait de valeurs multiples. faire cela signifie que vous obtenez
>>> def mv_identity(*args):
... return args
...
>>> mv_identity(1,2,3)
(1, 2, 3)
>>> # So far, so good. But what happens now with single arguments?
>>> mv_identity(1)
(1,)
Et régler ce problème pose rapidement d’autres problèmes, comme l’ont montré les différentes réponses données ici.
Donc, en résumé, il n'y a pas de fonction d'identité définie dans Python parce que:
Pour votre cas précis,
def dummy_gettext(message):
return message
est presque certainement ce que vous voulez - une fonction qui a la même convention d’appel et renvoie comme gettext.gettext
, qui retourne son argument sous forme inchangée, et qui est clairement nommée pour décrire ce qu’elle fait et où elle est destinée. Je serais assez choqué si la performance était une considération cruciale ici.
le vôtre fonctionnera bien. Lorsque le nombre de paramètres est correct, vous pouvez utiliser une fonction anonyme comme celle-ci:
lambda x: x
Non, il n'y en a pas.
Notez que votre identity
:
Will box ses arguments - c'est-à-dire.
In [6]: id = lambda *args: args
In [7]: id(3)
Out[7]: (3,)
Donc, vous voudrez peut-être utiliser lambda arg: arg
_ si vous voulez une vraie fonction d’identité.
NB: Cet exemple va masquer la fonction intégrée id
(que vous n'utiliserez probablement jamais).
Il n’existe pas de fonction d’identité intégrée en Python. Une imitation de la fonction id
de Haskell serait:
identity = lambda x, *args: (x,) + args if args else x
Exemple d'utilisation:
identity(1)
1
identity(1,2)
(1, 2)
Puisque identity
ne fait rien, à part le renvoi des arguments donnés, je ne pense pas que ce soit plus lent qu'une implémentation native. Cela peut même être plus rapide, car cela enregistre un appel à une fonction native.
gettext.gettext
(l'exemple d'utilisation du PO) accepte un seul argument, message
. Si on a besoin d'un talon pour cela, il n'y a aucune raison de renvoyer [message]
Au lieu de message
(def identity(*args): return args
). Ainsi les deux
_ = lambda message: message
def _(message):
return message
s'adapter parfaitement.
... mais une fonction intégrée serait certainement plus rapide (et éviterait les bugs introduits par moi-même).
Les bugs dans un cas aussi trivial sont à peine pertinents. Pour un argument de type prédéfini, par exemple str
, nous pouvons utiliser str()
elle-même en tant que fonction d'identité (à cause de chaîne interning elle conserve même l'identité de l'objet, voir id
note ci-dessous) et comparez ses performances avec la solution lambda:
$ python3 -m timeit -s "f = lambda m: m" "f('foo')"
10000000 loops, best of 3: 0.0852 usec per loop
$ python3 -m timeit "str('foo')"
10000000 loops, best of 3: 0.107 usec per loop
Une micro-optimisation est possible. Par exemple, le code Cython suivant:
test.pyx
cpdef str f(str message):
return message
Ensuite:
$ pip install runcython3
$ makecython3 test.pyx
$ python3 -m timeit -s "from test import f" "f('foo')"
10000000 loops, best of 3: 0.0317 usec per loop
Ne confondez pas une fonction d'identité avec la fonction intégrée id
qui renvoie l'identité d'un objet (signifiant un identifiant unique pour cet objet particulier plutôt que la valeur de cet objet, par rapport à l'opérateur ==
), son adresse mémoire en CPython.