为什么 ord() 在从 Python 2 移植到 Python 3 时失败? [英] Why does ord() fail when porting from Python 2 to Python 3?

查看:111
本文介绍了为什么 ord() 在从 Python 2 移植到 Python 3 时失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将名为 heroprotocol 的 Python 库从 Python 2 移植到 Python 3.这个库用于解析风暴英雄在线游戏的回放文件,目的是从文件中获取数据(即谁对阵谁,他们什么时候死,游戏什么时候结束,谁赢了等等).

这个库似乎是为 Python 2 创建的,由于我使用的是 Python 3(特别是 Anaconda、Jupyter notebook),我想将其转换为 Python 3.

我遇到的具体问题是当我运行时

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

应该得到一些关于重放文件的基本数据,我得到这个错误:

TypeError: ord() 预期长度为 1 的字符串,但找到了 int

我在 google 上搜索了 ord() 函数,发现了一些关于 Python 3 中 ord() 用法的帖子,但没有一个解决了我遇到的问题.我还尝试在 Github 的问题"部分发布,但没有得到任何回应

为什么我会看到这个错误?

解决方案

根据issue 您提出,异常发生在 decoders.py 的第 69 行:

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

这在 Python 2 中成功但在 Python 3 中失败的明显原因是 self._data 是一个字节串.在 Python 2 中,字节串是标准"字符串对象,因此索引到一个返回该位置的字符(本身是一个字符串)......

# Python 2.7>>>b'随便'[3]'t'

...并调用 ord() 结果如预期:

<预><代码>>>>ord(b'whatever'[3])116

然而,在 Python 3 中,一切都不同:标准字符串对象是一个Unicode字符串,而字节串则是整数序列.因此,对字节串进行索引会直接返回相关整数……

# Python 3.6>>>b'随便'[3]116

... 所以调用 ord() 在那个整数上没有意义:

<预><代码>>>>ord(b'whatever'[3])回溯(最近一次调用最后一次):文件<stdin>",第 1 行,位于 <module>类型错误:ord() 预期长度为 1 的字符串,但找到了 int

因此,您应该能够通过简单地删除该行和类似行上对 ord() 的调用来防止您在此处询问的特定异常:

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

……当然,结果很可能会揭示更多问题(超出本问题的范围).

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?

解决方案

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.

这篇关于为什么 ord() 在从 Python 2 移植到 Python 3 时失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆