4

不久前,我使用 2to3.py 脚本将我的几个文件转换为 Python 3。我相信我需要运行所有修复程序,所以我的命令包括

-f all -f buffer -f idioms -f set_literal -f ws_comma -w

我尝试使用 Python 3 运行转换后的代码,但出现错误

[Errno 22] 参数无效

在线上

stream.seek(-2,1)

stream 是一个用于解析文件的 StringIO 对象。这是 Python 2 和 3 中已知的差异,所以我应该使用不同的方法/语法吗?或者是 2to3 转换中的问题 - 也许我没有正确运行该工具。(我的意思是运行尽可能多的修复程序)

4

1 回答 1

3

我不确定,但我猜这是 3.x 中新的 Unicode 处理的牺牲品:

In [3]: file_ = open('/etc/services', 'r')

In [4]: file_.readline()
Out[4]: '# Network services, Internet style\n'

In [5]: file_.readline()
Out[5]: '#\n'

In [6]: file_.readline()
Out[6]: '# Note that it is presently the policy of IANA to assign a single well-known\n'

In [7]: file_.seek(-2, 1)
---------------------------------------------------------------------------
UnsupportedOperation                      Traceback (most recent call last)
<ipython-input-7-6122ef700637> in <module>()
----> 1 file_.seek(-2, 1)

UnsupportedOperation: can't do nonzero cur-relative seeks

但是,您可以使用二进制 I/O 来执行此操作:

In [9]: file_ = open('/etc/services', 'rb')

In [10]: file_.readline()
Out[10]: b'# Network services, Internet style\n'

In [11]: file_.readline()
Out[11]: b'#\n'

In [12]: file_.readline()
Out[12]: b'# Note that it is presently the policy of IANA to assign a single well-known\n'

In [13]: file_.seek(-2, 1)
Out[13]: 112

顺便说一句,如果你想在一段时间内保持双代码库,3to2 比 2to3 更有效。此外,许多人(包括我)很幸运地维护了在 2.x 和 3.x 上运行的单一代码库,而不是使用 2to3 或 3to2。

这是我提供的关于编写在 2.x 和 3.x 上运行的代码的演示文稿的链接:http: //stromberg.dnsalias.org/~dstromberg/Intro-to-Python/

PS:类似于StringIO,是BytesIO:

In [17]: file_ = io.BytesIO(b'abc def\nghi jkl\nmno pqr\n')

In [18]: file_.readline()
Out[18]: b'abc def\n'

In [19]: file_.seek(-2, 1)
Out[19]: 6
于 2013-12-05T23:53:56.890 回答