Génération dynamique de fonctions partielles en Python 2.7.x
-
20-12-2019 - |
Question
Supposons que je souhaite créer dynamiquement une fonction sur un shell IPython à partir du lambda suivant :
f = lambda x, ci: np.percentile(x, 100-ci)
ça corrige ci
à une nouvelle valeur.Ce serait quelque chose comme ce qui suit (create_new_f
c'est ce que je recherche).
ci = 20
new_f = create_new_f(f, ci=ci)
result = new_f([20,30,50,80])
J'ai essayé d'utiliser functools.partial
comme:
new_f = functools.partial(f, ci=20)
mais quand je lance ça dans un coque intégrée dans IPython, j'obtiens :
AttributeError: 'functools.partial' object has no attribute '__module__'
Y a-t-il alternative façon de faire cela, peut-être en utilisant des décorateurs ?
Contexte du sujet :
- Voici un IPython problème cela a suscité la question.
- Voici un fil expliquer le problème (et correctif dans Python 3.x seulement) aussi.
- Voici un autre fil dans SO qui montre le problème (voir le commentaire du haut)
- Pour une analyse encore plus approfondie de ce problème, voir ce problème en IPython.
encore une fois, ce que je recherche, c'est un alternative manière de procéder.
La solution
Solution pour IPython embarqué,
Vous pouvez implémenter avec une fermeture (je pense que cela peut être votre solution):
import numpy as np
def partial_f(ci):
def fn(x):
return np.percentile(x, 100-ci)
return fn
new_f = partial_f(20)
new_f([20,30,50,80])
Retour
62.000000000000014
Vérifier:
functools.partial
fonctionne pour moi dans le shell de mon IDE au travail :
import functools
import numpy as np
f = lambda x, ci: np.percentile(x, 100-ci)
ci = 20
new_f = functools.partial(f, ci=ci)
new_f([20,30,50,80])
Retour
62.000000000000014
Avec les lambdas (cela fonctionne dans le Shell en ligne IPython Je l'ai essayé, mais apparemment cela ne fonctionne pas pour votre cas) :
import numpy as np
pf = lambda ci: lambda x: np.percentile(x, 100-ci)
new_f2 = pf(20)
new_f2([20,30,50,80])
revient également
62.000000000000014