unicode_literals和type()

时间:2013-10-27 12:29:17

标签: python python-3.x python-2.x six-python

我在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()

  

“假”字节文字。数据应始终是正常的字符串文字。   在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 个答案:

答案 0 :(得分:14)

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

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