【问题标题】:Change string type used for ‘print’ argument type coercion更改用于“打印”参数类型强制的字符串类型
【发布时间】:2016-01-05 13:18:54
【问题描述】:

如何说服 Python 2 的 print 将其参数强制转换为 unicode

Python 2 print 功能,无论是语句还是函数,显然都将其参数强制转换为字节类型 str

>>> import sys
>>> import io
>>> sys.version_info[0:2]
(2, 7)

>>> print >> sys.stderr, None
None
>>> print >> io.StringIO(), None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unicode argument expected, got 'str'

print 变成一个函数并没有帮助;无论如何,相同的内部参数处理似乎发生在 Python 2 上:

>>> from __future__ import print_function
>>> import sys
>>> import io
>>> sys.version_info[0:2]
(2, 7)

>>> print(None, file=sys.stderr)
None
>>> print(None, file=io.StringIO())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unicode argument expected, got 'str'

由于我想用 io.StringIO 实例替换标准流(以使代码在 Python 2 和 Python 3 下的测试套件中运行),所以上述失败让我死了。

使用 io.BytesIO 实例可以在 Python 2 的 print 上工作,但在 Python 3 的 print 上会中断。并且目标是让代码尽可能使用 Unicode,因此io.BytesIO 不是一个可接受的解决方案。

我需要print每个输出都是 Unicode,而不是字节。

如何更改print 用于强制输出参数的类型,并改用Unicode 文本类型unicode

【问题讨论】:

  • 一个简单的解决方案是使用io.BytesIO()
  • 如果您在 Python 的内置 unittest 框架中运行,使用 buffer 参数可能会为您完成这项工作。没有那个,我相信我已经成功地将sys.stdout 替换为只需要一两个函数的模拟对象,但这是一段时间前的事情,所以我不记得了。
  • 你试过from python23compat import print吗?
  • 我在 python 2.7 中遇到了与 io.StringIO 相同的错误。切换到 StringIO.StringIO() 对我有用。

标签: python unicode compatibility python-2.x type-coercion


【解决方案1】:

对于 print>>,您需要一个带有 .write 方法的对象,该方法接受字符串。我觉得没有其他办法了。

您可以创建一个包装器将 str 转换为 unicode

class a(object):
  def __init__(self, b):
    self.b=b
  def write(self, s):
    self.b.write(unicode(s,'utf-8'))

buf=io.StringIO()
print >> a(buf), '...'

【讨论】:

    【解决方案2】:

    非常混乱,但也许这有一些有用的东西:

    import sys
    import io
    
    if sys.version_info >= (3, 0):
        bytes_out = io.BytesIO()
        out_buffer = io.TextIOWrapper(bytes_out, encoding="utf-8")
    else:
        out_buffer = io.BytesIO()
    
    # print now supports all variants
    print(None, file=out_buffer)
    print(b"hello", file=out_buffer)
    print("£", file=out_buffer)
    
    out_buffer.flush()
    out_buffer.seek(0)
    
    if sys.version_info >= (3, 0):
        my_unicode = out_buffer.read()
    else:
        my_unicode = out_buffer.read().decode("utf-8")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-14
      • 2011-10-06
      • 1970-01-01
      • 2013-05-30
      • 1970-01-01
      • 2019-03-20
      • 1970-01-01
      • 2017-05-16
      相关资源
      最近更新 更多