У меня возникают проблемы с поддержкой python2 и python3 при вызове type()
. Это демонстрирует проблему:
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
Это связано с Любые ошибки с использованием unicode_literals в Python 2.6?. В этом вопросе кто-то рекомендует typecasting для байта, так что наивно я думал об использовании six.b()
:
A "поддельный" байтовый литерал. данные всегда должны быть нормальным строковым литералом. В 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 была python3 bytestring на python2, но ему нужна строка python3, которая представляет собой строку юникода python2 на python3.
Как вы думаете?
Я что-то не понимаю?
Или существует ли реальная несовместимость с type()
на python 2 и 3?
Нет ли способа иметь один и тот же вызов type()
, поддерживающий как 2, так и 3?
Не должен ли инструмент, подобный six
, обернуть вокруг type()
в этом случае?