afficher la d=c3=a9finition d'une fonction =c3=a0 partir de la console

10 réponses
Avatar
Fabrice
Bonjour,

imaginons que j'ai écrit une fonction dans la console.

def f(x):
if x<0: return -1
else : return 1

je suis toujours dans la console.
Existe-t-il le moyen d'afficher la définition de la fonction f ?

Du genre, je tape

>>> AFFICHE_DEF(f)

et je vois apparaître

def f(x):
if x<0: return -1
else : return 1

Je pense à cette idée puisque Python est interprété donc on a forcément
accès au code source...

Merci,
Fabrice.

---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus

10 réponses

Avatar
yves
Le Sun, 01 Sep 2019 21:29:18 +0200, Fabrice a écrit:
Bonjour,
je suis toujours dans la console.
Existe-t-il le moyen d'afficher la définition de la fonction f ?

Pas vraiment possible d'après cette discussion:
https://stackoverflow.com/questions/2193231/display-function-definition-
in-interactive-shell
sauf ce hack sous linux:
import readline
readline.write_history_file('/tmp/hist.txt')
et lire hist.txt
Ceci dit, si tu penses vraiment avoir besoin de faire ça (si ce n'est pas
juste une question théorique), ça signifie, à mon avis et sauf
démonstration du contraire, que ta façon de travailler n'est pas optimale.
@+
--
Yves
Avatar
Fabrice
Le 02/09/2019 à 10:38, yves a écrit :
ta façon de travailler n'est pas optimale.

Je ne cherche pas à travailler mais à enseigner ;-)
et parfois, mes élèves s'emmêlent les pinceaux et croient utiliser une
fonction alors que c'en est une autre... surtout avec jupyter qui permet
de réexécuter les cadres de code passés.
Du coup, lorsqu'ils m'appellent au secours, ils ont parfois un
"programme" qui semblent bon mais qui ne marche pas car l'erreur est
dans une fonction qu'ils appellent et qui n'est pas celle qu'ils croient.
Et quand ils me disent : "Mais si m'sieur, j'ai bien écrit ma fonction"
en me montrant le cadre de code qu'ils ont changé mais pas exécuté,
j'aimerai leur montrer ce que Python connait vraiment.
Cordialement,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Becaree
La réponse la plus simple que je pourrais vous donner est https://grou ps.google.com/forum/#!topic/fr.comp.lang.python/GPrPTowK6C0. Donc pas de gl obals beaucoup moins de soucis et sinon le code doit etre écrit quelqu e part, il y a des moyen d'accéder aux noms du module auxquel appartie nt une fonction avec:
import sys
getattr(sys.modules[__name__], 'f')
Cependant vous ne verrez la fonction qui est disponible dans les globaux se ulement
C'est à dire si vous avez appeler une variable math, le module pass à l'oubliette. Quand au fait python est interprété, oui, et cela veut dire qu'a un moment dans l'interpreteur y'a eu des méthodes avec exec, eval et compile dont on pourrait très bien "affiché le corps" mais vous allez pas faire coder vos élèves ainsi
Avatar
Benoit Izac
Bonjour,
Le 03/09/2019 à 09:01, Fabrice a écrit dans le message
<5d6e0fbd$0$3528$ :
et parfois, mes élèves s'emmêlent les pinceaux et croient utiliser une
fonction alors que c'en est une autre... surtout avec jupyter qui
permet de réexécuter les cadres de code passés.
Du coup, lorsqu'ils m'appellent au secours, ils ont parfois un
"programme" qui semblent bon mais qui ne marche pas car l'erreur est
dans une fonction qu'ils appellent et qui n'est pas celle qu'ils
croient.
Et quand ils me disent : "Mais si m'sieur, j'ai bien écrit ma
fonction" en me montrant le cadre de code qu'ils ont changé mais pas
exécuté, j'aimerai leur montrer ce que Python connait vraiment.

Le problème c'est que, bien que Python soit interprété, il exécute du
bytecode. Donc le seul moyen est de désassembler le bytecode mais c'est
plus compliqué à lire car tu obtiens un genre d'assembleur. Sur ta
fonction « f » :
def f(x):



... if x<0: return -1
... else : return 1
...
import dis
dis.dis(f)



2 0 LOAD_FAST 0 (x)
2 LOAD_CONST 1 (0)
4 COMPARE_OP 0 (<)
6 POP_JUMP_IF_FALSE 12
8 LOAD_CONST 2 (-1)
10 RETURN_VALUE
3 >> 12 LOAD_CONST 3 (1)
14 RETURN_VALUE
16 LOAD_CONST 0 (None)
18 RETURN_VALUE
Voir <https://docs.python.org/3/library/dis.html> pour plus de détail.
--
Benoit Izac
Avatar
Nicolas
Bonjour,
et parfois, mes élèves s'emmêlent les pinceaux et croient utiliser une
fonction alors que c'en est une autre... surtout avec jupyter qui permet
de réexécuter les cadres de code passés.
Du coup, lorsqu'ils m'appellent au secours, ils ont parfois un
"programme" qui semblent bon mais qui ne marche pas car l'erreur est
dans une fonction qu'ils appellent et qui n'est pas celle qu'ils croient.
Et quand ils me disent : "Mais si m'sieur, j'ai bien écrit ma fonction"
en me montrant le cadre de code qu'ils ont changé mais pas exécuté,
j'aimerai leur montrer ce que Python connait vraiment.

D'après cette réponse
(https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function/427533#427533),
il semblerait que les lignes suivantes fonctionnent dans jupyter :
import inspect
print(inspect.getsource(fonction))
A vérifier...
Je n'utilise pas jupyter, donc, je ne peux pas vérifier ;)
Nicolas
Avatar
Benoit Izac
Bonjour,
Le 06/09/2019 à 08:43, Nicolas a écrit dans le message
<5d71fffd$0$15180$ :
et parfois, mes élèves s'emmêlent les pinceaux et croient utiliser
une fonction alors que c'en est une autre... surtout avec jupyter
qui permet de réexécuter les cadres de code passés.
Du coup, lorsqu'ils m'appellent au secours, ils ont parfois un
"programme" qui semblent bon mais qui ne marche pas car l'erreur est
dans une fonction qu'ils appellent et qui n'est pas celle qu'ils
croient.
Et quand ils me disent : "Mais si m'sieur, j'ai bien écrit ma
fonction" en me montrant le cadre de code qu'ils ont changé mais pas
exécuté, j'aimerai leur montrer ce que Python connait vraiment.

D'après cette réponse
(https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function/427533#427533),
il semblerait que les lignes suivantes fonctionnent dans jupyter :
import inspect
print(inspect.getsource(fonction))
A vérifier...
Je n'utilise pas jupyter, donc, je ne peux pas vérifier ;)

Ce n'est pas spécifique à Jupyter et tu as lu un peu vite :
| If the function is from a source file available on the filesystem,
| [...]
| But I believe that if the function is compiled from a string, stream
| or imported from a compiled file, then you cannot retrieve its source
| code.
Lorsque le code est tapé dans la console, le fichier source n'est pas
disponible donc ça ne fonctionne pas. Ça ne marche que ce que tu vas
trouver dans /usr/lib/pythonX.X/.
--
Benoit Izac
Avatar
Fabrice
Bonjour,
j'utilise Anaconda à la maison et dans la console de spyder, la méthode
proposé par Nicolas fonctionne très bien.
Elle fonctionne aussi dans Jupyter.
Merci Nicolas.
cordialement,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Nicolas
Le 06/09/2019 à 19:25, Benoit Izac a écrit :
Bonjour,
Le 06/09/2019 à 08:43, Nicolas a écrit dans le message
<5d71fffd$0$15180$ :
et parfois, mes élèves s'emmêlent les pinceaux et croient utiliser
une fonction alors que c'en est une autre... surtout avec jupyter
qui permet de réexécuter les cadres de code passés.
Du coup, lorsqu'ils m'appellent au secours, ils ont parfois un
"programme" qui semblent bon mais qui ne marche pas car l'erreur est
dans une fonction qu'ils appellent et qui n'est pas celle qu'ils
croient.
Et quand ils me disent : "Mais si m'sieur, j'ai bien écrit ma
fonction" en me montrant le cadre de code qu'ils ont changé mais pas
exécuté, j'aimerai leur montrer ce que Python connait vraiment.

D'après cette réponse
(https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function/427533#427533),
il semblerait que les lignes suivantes fonctionnent dans jupyter :
import inspect
print(inspect.getsource(fonction))
A vérifier...
Je n'utilise pas jupyter, donc, je ne peux pas vérifier ;)

Ce n'est pas spécifique à Jupyter et tu as lu un peu vite :

Non non, je n'ai pas lu trop vite :
"to my surprise, it works in Ipython/Jupyter notebooks also – Dr. Goulu
Jan 22 '16 at 11:51"
;)
Avatar
Nicolas
Le 07/09/2019 à 18:56, Fabrice a écrit :
Bonjour,
j'utilise Anaconda à la maison et dans la console de spyder, la méthode
proposé par Nicolas fonctionne très bien.
Elle fonctionne aussi dans Jupyter.
Merci Nicolas.

De rien :)
cordialement,
Fabrice.
---
L'absence de virus dans ce courrier électronique a été vérifiée par le
logiciel antivirus Avast.
https://www.avast.com/antivirus
Avatar
Benoit Izac
Bonjour,
Le 09/09/2019 à 08:32, Nicolas a écrit dans le message
<5d75f1f4$0$6460$ :
et parfois, mes élèves s'emmêlent les pinceaux et croient utiliser
une fonction alors que c'en est une autre... surtout avec jupyter
qui permet de réexécuter les cadres de code passés.
Du coup, lorsqu'ils m'appellent au secours, ils ont parfois un
"programme" qui semblent bon mais qui ne marche pas car l'erreur est
dans une fonction qu'ils appellent et qui n'est pas celle qu'ils
croient.
Et quand ils me disent : "Mais si m'sieur, j'ai bien écrit ma
fonction" en me montrant le cadre de code qu'ils ont changé mais pas
exécuté, j'aimerai leur montrer ce que Python connait vraiment.

D'après cette réponse
(https://stackoverflow.com/questions/427453/how-can-i-get-the-source-code-of-a-python-function/427533#427533),
il semblerait que les lignes suivantes fonctionnent dans jupyter :
import inspect
print(inspect.getsource(fonction))
A vérifier...
Je n'utilise pas jupyter, donc, je ne peux pas vérifier ;)

Ce n'est pas spécifique à Jupyter et tu as lu un peu vite :

Non non, je n'ai pas lu trop vite :
"to my surprise, it works in Ipython/Jupyter notebooks also – Dr.
Goulu Jan 22 '16 at 11:51"

C'est plutôt moi qui n'ai pas tout lu. ;-)
Et c'est parce qu'il garde une trace du code source (dans
~/.ipython/profile_default/history.sqlite chez moi). D'un autre coté, il
suffit d'utiliser la flèche du haut pour voir ce qui a été exécuté en
dernier.
--
Benoit Izac