Python 2.7 / exec / was ist falsch?
Frage
Ich habe diesen Code, die fein in Python 2.5 läuft aber nicht in 2.7:
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"
""")
Und ich:
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'
Lösung
io.StringIO
ist verwirrend in Python 2.7, weil es von der 3.x-Bytes / string Welt zurückportiert wird. Dieser Code wird die gleichen Fehler wie bei Ihnen:
from io import StringIO
sio = StringIO()
sio.write("Hello\n")
Ursachen:
Traceback (most recent call last):
File "so2.py", line 3, in <module>
sio.write("Hello\n")
TypeError: string argument expected, got 'str'
Wenn Sie nur 2.x Python verwenden, dann lassen Sie den io
Modul zusammen, und Stick mit StringIO. Wenn Sie wirklich io
verwenden möchten, ändern Sie Ihre Import:
from io import BytesIO as StringIO
Andere Tipps
Es ist eine schlechte Nachricht
io.StringIO will mit Unicode an der Arbeit. Man könnte denken, Sie es, indem man ein u
vor dem String beheben können Sie dieses
print "%s" % CaptureExec("""
import random
print u"hello world"
""")
jedoch print
ist wirklich für diese gebrochen, wie es bewirkt, dass zwei Schreibvorgänge in die StringIO. Die erste ist u"hello world"
was in Ordnung ist, aber dann folgt es mit "\n"
so stattdessen Sie schreiben müssen, so etwas wie dieses
print "%s" % CaptureExec("""
import random
sys.stdout.write(u"hello world\n")
""")