Почему ord() терпит неудачу при переносе с Python 2 на Python 3?

Я пытаюсь перенести библиотеку Python с именем heroprotocol с Python 2 на Python 3. Эта библиотека используется для анализа файлов воспроизведения из онлайн-игры под названием Heroes of the Storm с целью получения данных из файла (т.е. кто играл против кого, когда они умерли, когда закончилась игра, кто победил и т. д.).

Кажется, что эта библиотека была создана для Python 2, и, поскольку я использую Python 3 (в частности, Anaconda, ноутбук Jupyter), я хотел бы преобразовать ее в Python 3.

Конкретная проблема у меня заключается в том, что когда я бегу

header = protocol.decode_replay_header(mpq.header['user_data_header']['content'])

который должен получить некоторые основные данные о файле воспроизведения, я получаю эту ошибку:

TypeError: ord() expected string of length 1, but int found

Я погуглил ord() функции и нашел несколько постов об использовании ord() в Python 3, но ни один из них не решил проблему, с которой я столкнулся. Я также попытался опубликовать в разделе "Проблемы" на Github, но я еще не получил ответа.

Почему я вижу эту ошибку?

1 ответ

Согласно поднятой проблеме, исключение происходит в строке 69 файла decoders.py:

self._next = ord(self._data[self._used])

Очевидная причина, по которой это удалось бы в Python 2, но не в Python 3, заключается в том, что self._data это строка В Python 2 байтовые строки являются "стандартными" строковыми объектами, так что индексирование по одному возвращает символ в этой позиции (сама строка)…

# Python 2.7
>>> b'whatever'[3]
't'

... и зовет ord() На результат ведет себя как положено:

>>> ord(b'whatever'[3])
116

Однако в Python 3 все по-другому: стандартный строковый объект - это строка Unicode, а байтовые строки - это последовательности целых чисел. Из-за этого индексирование в строку байтов возвращает соответствующее целое число напрямую…

# Python 3.6
>>> b'whatever'[3]
116

… Так зовет ord() на это целое число не имеет смысла:

>>> ord(b'whatever'[3])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: ord() expected string of length 1, but int found

Таким образом, вы должны быть в состоянии предотвратить конкретное исключение, о котором вы здесь спрашиваете, просто удалив вызов ord() на том же и подобных строках:

self._next = self._data[self._used]

… Хотя, конечно, вполне вероятно, что в результате будут выявлены дальнейшие проблемы (выходящие за рамки этого вопроса).

Другие вопросы по тегам