2010-08-06 19 views
5

tengo este código que funciona muy bien en Python 2.5, pero no en 2.7:python 2.7/exec/¿qué está mal?

import sys 
import traceback 
try: 
    from io import StringIO 
except: 
    from StringIO import StringIO 

def CaptureExec(stmt): 
    oldio = (sys.stdin, sys.stdout, sys.stderr) 
    sio = StringIO() 
    sys.stdout = sys.stderr = sio 
    try: 
     exec(stmt, globals(), globals()) 
     out = sio.getvalue() 
    except Exception, e: 
     out = str(e) + "\n" + traceback.format_exc() 
    sys.stdin, sys.stdout, sys.stderr = oldio 
    return out 

print "%s" % CaptureExec(""" 
import random 
print "hello world" 
""") 

Y consigo:

 
string argument expected, got 'str' 
Traceback (most recent call last): 
    File "D:\3.py", line 13, in CaptureExec 
    exec(stmt, globals(), globals()) 
    File "", line 3, in 
TypeError: string argument expected, got 'str' 
+2

comentarios de menor importancia: el estilo Pythonic es utilizar TitleCase para las clases solamente, debe ser 'captureExec' o' capture_exec'. Además, debería atrapar 'ImportError' específicamente en el bloque' try ... except'. – katrielalex

Respuesta

14

io.StringIO es confuso en Python 2.7 porque está portado a partir de los bytes 3.x/string world. Este código obtiene el mismo error que el suyo:

from io import StringIO 
sio = StringIO() 
sio.write("Hello\n") 

causas:

Traceback (most recent call last): 
    File "so2.py", line 3, in <module> 
    sio.write("Hello\n") 
TypeError: string argument expected, got 'str' 

Si sólo está utilizando Python 2.x, luego salte el módulo io por completo, y se pega con StringIO. Si realmente desea utilizar io, cambiar su importación a:

from io import BytesIO as StringIO 
+0

+1 para 'BytesIO'. Creo que un montón de código 2.x antiguo no va a ser muy compatible con 2.7:/Parece que 2.7 va a ser un paso más hacia 3.x –

2

Es una mala noticia

io.StringIO quiere trabajar con Unicode. Se podría pensar que se puede solucionar poniendo un u delante de la cadena que desea imprimir como esto

print "%s" % CaptureExec(""" 
import random 
print u"hello world" 
""") 

embargo print que realmente está roto para esto ya que hace 2 escribe a los StringIO. La primera de ellas es u"hello world" lo cual está bien, pero luego se sigue con "\n"

lo que en lugar que necesita para escribir algo como esto

print "%s" % CaptureExec(""" 
import random 
sys.stdout.write(u"hello world\n") 
""") 
Cuestiones relacionadas