问题
I am trying to port a Python library called heroprotocol from Python 2 to Python 3. This library is used to parse replay files from an online game called Heroes of the Storm, for the purpose of getting data from the file (i.e. who played against who, when did they die, when did the game end, who won, etc).
It seems that this library was created for Python 2, and since I am using Python 3 (specifically Anaconda, Jupyter notebook) I would like to convert it to Python 3.
The specific issue I am having is that when I run
header = protocol.decode_replay_header(mpq.header['user_data_header']['content'])
which should get some basic data about the replay file, I get this error:
TypeError: ord() expected string of length 1, but int found
I googled the ord()
function and found a few posts about the usage of ord()
in Python 3, but none of them solved the issue I am having. I also tried posting in the "Issues" section on Github, but I got no response yet.
Why am I seeing this error?
回答1:
According to the issue you raised, the exception occurs on line 69 of decoders.py:
self._next = ord(self._data[self._used])
The obvious reason this would succeed in Python 2 but fail in Python 3 is that self._data
is a bytestring. In Python 2, bytestrings are the "standard" string objects, so that indexing into one returns the character at that position (itself a string) …
# Python 2.7
>>> b'whatever'[3]
't'
… and calling ord() on the result behaves as expected:
>>> ord(b'whatever'[3])
116
However, in Python 3, everything is different: the standard string object is a Unicode string, and bytestrings are instead sequences of integers. Because of this, indexing into a bytestring returns the relevant integer directly …
# Python 3.6
>>> b'whatever'[3]
116
… so calling ord() on that integer makes no sense:
>>> 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
So, you ought to be able to prevent the specific exception you're asking about here by simply removing the call to ord()
on that and similar lines:
self._next = self._data[self._used]
… although of course it's likely that further problems (out of scope for this question) will be revealed as a result.
来源:https://stackoverflow.com/questions/47260954/why-does-ord-fail-when-porting-from-python-2-to-python-3