unicode_literals 和 type()

Posted

技术标签:

【中文标题】unicode_literals 和 type()【英文标题】:unicode_literals and type() 【发布时间】:2013-11-06 05:39:26 【问题描述】:

我在type() 调用中支持 python2 和 python3 时遇到问题。这说明了问题:

from __future__ import unicode_literals

name='FooClass'
type(name, (dict,), )

在python3上没问题,但是在python2上:

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    type(name, (dict,), )
TypeError: type() argument 1 must be string, not unicode

这与Any gotchas using unicode_literals in Python 2.6? 有关。在那个问题中,有人建议将类型转换为字节串,所以我天真地考虑使用six.b()

“假”字节文字。 data 应该始终是一个普通的字符串文字。 在 Python 2 中,b() 返回一个 8 位字符串。在 Python 3 中,数据被编码 将 latin-1 编码为字节。

所以它看起来像这样:

from __future__ import unicode_literals
import six

name='FooClass'
type(six.b(name), (dict,), )

但它在 python2 和 python3 上都失败了:

$ python2 test.py 
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    type(six.b(name), (dict,), )
TypeError: type() argument 1 must be string, not unicode

$ python3 test.py 
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    type(six.b(name), (dict,), )
TypeError: type() argument 1 must be str, not bytes

看来真的type() 想要一个 python2 str,它是 python2 上的一个 python3 字节字符串,但它想要一个 python3 str,它是 python3 上的一个 python2 unicode 字符串。

你怎么看?

有什么我不明白的地方吗?

或者在 python 2 和 3 上与 type() 是否存在真正的不兼容?

难道没有任何方法可以让相同的type() 呼叫同时支持 2 和 3 吗?

在这种情况下,像 six 这样的工具不应该为 type() 提供一个包装器吗?

【问题讨论】:

谢谢,这行得通,但我确信我已经测试过了...... 【参考方案1】:

six.b 是在您不会使用 unicode_literals 的假设下编写的(并且您将向它传递一个字符串文字,如文档所述),因此 Python 2 实现只是 def b(s): return s 为Python 2 字符串文字已经是一个字节字符串。

要么不要在这个模块中使用unicode_literals,要么使用(如评论所示)str(name)。在 Python 3 中,这是一个空操作。在 Python 2 中,它默默地将 unicode 字符串转换为字节字符串(假设有一些我懒得记住的编码,但它是 ASCII 的超集,所以你应该没问题)。

【讨论】:

以上是关于unicode_literals 和 type()的主要内容,如果未能解决你的问题,请参考以下文章

python 测试“from __future__ import unicode_literals”的范围

from __future__ import unicode_literals, absolute_import

使用from __future__ import unicode_literals

Python基础之--from __future__ import unicode_literals作用

没有名为 future 的模块

使用RNN对文本进行分类实践电影评论