python 2.7 / exec /有什么问题?

时间:2010-08-06 12:10:27

标签: python redirect exec stdio stringio

我有这个代码在Python 2.5中运行良好但在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"
""")

我得到了:

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 个答案:

答案 0 :(得分:14)

io.StringIO在Python 2.7中令人困惑,因为它从3.x字节/字符串世界向后移植。此代码与您的错误相同:

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

导致:

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

如果您只使用Python 2.x,则完全跳过io模块,并坚持使用StringIO。如果您确实想使用io,请将导入更改为:

from io import BytesIO as StringIO

答案 1 :(得分:2)

这是个坏消息

io.StringIO想要使用unicode。您可能认为可以通过将u放在要打印的字符串前面来修复它

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

然而print真的被打破了,因为它导致2次写入StringIO。第一个是u"hello world",这很好,但随后是"\n"

所以你需要写这样的东西

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