代码之家  ›  专栏  ›  技术社区  ›  Elias Bachaalany

Python2.7/exec/怎么了?

  •  5
  • Elias Bachaalany  · 技术社区  · 14 年前

    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 回复  |  直到 14 年前
        1
  •  14
  •   Ned Batchelder    14 年前

    io.StringIO 在Python2.7中是令人困惑的,因为它是从3.x bytes/string世界进行后端口的。此代码与您的错误相同:

    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'
    

    如果您只使用python2.x,那么跳过 io 模块,并坚持使用StringIO。如果你真的想用 ,将导入更改为:

    from io import BytesIO as StringIO
    
        2
  •  2
  •   John La Rooy    14 年前

    这是个坏消息

    io.StringIO希望使用unicode。你可能认为你可以通过放一个 u 在你想这样打印的字符串前面

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

    print 因为它会导致对StringIO的2次写入,所以它实际上是坏的。第一个是 u"hello world" "\n"

    所以你需要写这样的东西

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