проблема миграции с python2 на python3 с юникодом и байтами - PullRequest
0 голосов
/ 04 мая 2019

Я обновил пакет Python2 для поддержки Python3, и застрял при обработке одного тестового примера, который завершается неудачно в Python3 из-за некоторых проблем кодирования. Пакет обычно занимается стандартизацией URL-адресов и выполняет некоторые пользовательские преобразования до или после выгрузки в несколько библиотек PyPi.

В Python2 у меня могут быть две строки, которые являются кодировками одного и того же URL как таковые:

url_a = u'http://➡.ws/♥'
url_b =  'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'

, для которых выполняются следующие условия:

url_a.encode('utf-8') == url_b
>>> True
type(url_a.encode('utf-8')) == str
>>> True

После нескольких разных маршрутов они оба стандартизированы в Punycode

url_result = 'http://xn--hgi.ws/%E2%99%A5'

В Python3 я бью стену, потому что url_a.encode('utf-8') возвращает bytestring, что является обязательным объявлением при определении переменной в этом формате.

url_a.encode('utf-8')
>>> b'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'
url_a.encode('utf-8') == url_b
>>> False
type(url_a.encode('utf-8')) == str
>>> True
type(url_a.encode('utf-8')) == bytes
>>> True

Я не могу найти способ выполнения операций над url_b, чтобы он был закодирован / декодирован так, как мне требуется.

Который я мог бы просто определить в моем тестовом примере с помощью объявления строки байтов, и все пройдет в обеих средах ...

url_a = u'http://➡.ws/♥'
url_b = b'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'

все еще существует вероятность того, что что-то прервется в работе из-за данных в очередях обмена сообщениями или базах данных, которые еще не были обработаны.

по сути, в Python3 мне нужно обнаружить такую ​​короткую строку, как

url_b = 'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'

должен был быть объявлен как строка

url_b = b'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'

и конвертируйте его правильно, потому что он интерпретируется как

url_b
>>> 'http://â\x9e¡.ws/â\x99¥'

edit: Ближайшее, что я получил, это url_b.decode('unicode-escape'), которое генерирует b'http://\\xe2\\x9e\\xa1.ws/\\xe2\\x99\\xa5'

Ответы [ 2 ]

2 голосов
/ 04 мая 2019

Вы хотите .encode(), а не .decode(), а 'raw_unicode_escape':

#!/usr/bin/env python
# -*- coding: utf-8 -*-

url_a = u'http://➡.ws/♥'
url_b =  'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'

encoded_a = url_a.encode('utf-8')
try:
    # Python 3
    encoded_b = url_b.encode('raw_unicode_escape')
except UnicodeDecodeError:
    # Python 2
    encoded_b = url_b

print(repr(encoded_a))
print(repr(encoded_b))

# Output is as follows (without the leading 'b' in Python 2):
#   b'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'
#   b'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'
0 голосов
/ 04 мая 2019

Код:

url_b = b'http://\xe2\x9e\xa1.ws/\xe2\x99\xa5'
print(url_b.decode("utf-8"))

Выход:

http://➡.ws/♥
...