【问题标题】:python 2.7 / exec / what is wrong?python 2.7 / exec / 出了什么问题?
【发布时间】:2011-03-26 07:32:53
【问题描述】:

我的这段代码在 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"
""")

我得到:

需要字符串参数,得到'str' 回溯(最近一次通话最后): CaptureExec 中的文件“D:\3.py”,第 13 行 执行(stmt,全局(),全局()) 文件“”,第 3 行,在 TypeError:需要字符串参数,得到'str'

【问题讨论】:

  • Minor cmets:Pythonic 风格是只对类使用 TitleCase,它应该是 captureExeccapture_exec。此外,您应该专门在 try...except 块中捕获 ImportError

标签: python redirect exec stdio stringio


【解决方案1】:

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 表示BytesIO。我认为很多旧的 2.x 代码不会与 2.7 非常兼容:/ 似乎 2.7 将更像是通向 3.x 的垫脚石
【解决方案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")
""")

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    • 2011-10-30
    • 2013-05-19
    • 1970-01-01
    相关资源
    最近更新 更多