Почему 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]
… Хотя, конечно, вполне вероятно, что в результате будут выявлены дальнейшие проблемы (выходящие за рамки этого вопроса).