Récupérer la sortie de print ?

Dans l'hypothèse d'une implémentation d'une saisie "direct" du code sur la carte Micro Python, la question qui se pose est de récupérer la sortie de print et plus généralement de eval ou de exec sous forme d'une chaine exploitable.

via stdout ?

voir : https://stackoverflow.com/questions/3906232/python-get-the-print-output-in-an-exec-statement

code = """
i = [0,1,2]
for j in i :
print j
"""

from cStringIO import StringIO
old_stdout = sys.stdout
redirected_output = sys.stdout = StringIO()
exec(code)
sys.stdout = old_stdout

print redirected_output.getvalue()

Cette solution ne fonctionne pas en Micropython, crée une erreur.

overrider la fonction print

Cette solution est assez simple et permet de résoudre facilement la récupération d'une chaine :

>>> a=print('test')
test
>>> a
>>> def new_print(strIn):
...     return strIn
...
>>> print=new_print
>>> a=print("test")
>>> a
'test'
>>> b=eval("print('test')")
>>> b
'test'
>>> c=exec("print('test')")
>>> c
>>>

voir ici : https://stackoverflow.com/questions/20885760/how-to-get-back-an-overridden-python-built-in-function

Noter que future n'est pas forcément disponible et est ici : https://github.com/micropython/micropython-lib

passer une globale

Par contre la solution précédente ne fonctionne pas avec exec

Une solution qui semble fonctionner est de passer par une variable globale et d'utiliser une fonction print overridée qui vient modifier cette variable.

>>> out=1
>>> c=exec("""global out
... out=3""")
>>> out
3
>>> def new_print(strIn):
...     global out
...     out=strIn
...
>>> print=new_print
>>> print("T")
>>> out
'T'
>>> exec("""global out
... a=56
... print(str(a))
... """)
>>> out
'56'

Au final, çà donnerait un main.py avec print overidée, variable globale, et qui gérerait le chargement du code qui lui serait dans un autre fichier que le main.py gèrerait en fonction des actions utilisateur. Et là, çà le fait. Avec du try except en plus bien utilisé dans le code passé à