Что делать, в мире, где все текстовые литералы по умолчанию имеют Unicode, чтобы сделать __import__
работать как на Python 2, так и на 3?Портативный код: __import__ тип строки параметров между Python 2 и Python 3
Я медленно узнаю о создании кода Python, который будет работать как под Python 2 (версия 2.6, так и выше) и Python 3 (версия 3.2 или выше).
Это влечет за собой, я считаю, увещевание для обеспечения текстовых литералов являются Unicode по умолчанию:
from __future__ import unicode_literals
и указать байты литералов явно с b'wibble'
, если это необходимо.
__import__
встроенная функция, однако, срабатывание.
Хитрый, тривиальный макет проекта:
$ mkdir fooproject/
$ cd fooproject/
$ mkdir foo/
$ printf "" > foo/__init__.py
$ mkdir foo/bar/
$ printf "" > foo/bar/__init__.py
Вот простой fooproject/setup.py
для этого проекта:
from __future__ import unicode_literals
main_module_name = 'foo'
main_module = __import__(main_module_name, fromlist=['bar'])
assert main_module.bar
Это терпит неудачу под Python 2, но прекрасно работает под Python 3:
$ python2 ./setup.py
Traceback (most recent call last):
File "./setup.py", line 4, in <module>
main_module = __import__(main_module_name, fromlist=['bar'])
TypeError: Item in ``from list'' not a string
$ python3 ./setup.py
Мы намеренно сделали unadorned строки Unicode по умолчанию. «Не строка », я предполагаю, что Python 2 означает «не« объект байтов ».
Итак, мы явно установить, что к bytes
буквальным:
from __future__ import unicode_literals
main_module_name = 'foo'
main_module = __import__(main_module_name, fromlist=[b'bar'])
assert main_module.bar
Теперь Python 2 выполняется, но Python 3 жалуется:
$ python2 ./setup.py
$ python3 ./setup.py
Traceback (most recent call last):
File "./setup.py", line 4, in <module>
main_module = __import__(main_module_name, fromlist=[b'bar'])
File "<frozen importlib._bootstrap>", line 2281, in
_handle_fromlist
TypeError: hasattr(): attribute name must be string
Так что я намеренно прикрас строки по умолчанию для Unicode, как и я; но это, очевидно, нарушая ожидания __import__
между Python 2 и Python 3.
Как я могу получить, что __import__
вызов, в комплекте с параметром fromlist
, правильно работает под как Python 2 и Python 3, сохраняя настройки unicode_literals
?
Вы могли бы написать функцию, вы передаете строку и он проверяет версию и возвращает версию unicode или bytestring. – BrenBarn
@BrenBarn, вот как ведет себя 'str()'! –