Ошибка остается после запуска 2to3.py в модуле

Некоторое время назад я использовал скрипт 2to3.py для преобразования нескольких моих файлов в Python 3. Я считаю, что мне нужно запустить все фиксеры, поэтому моя команда включала

-f все -f буфер -f идиомы -f set_literal -f ws_comma -w

Я попытался запустить свой преобразованный код с помощью Python 3, но получил ошибку

[Errno 22] Неверный аргумент

на линии

stream.seek(-2,1)

stream — это объект StringIO, который используется для разбора файла. Это известная разница в Python 2 и 3, поэтому я должен использовать разные методы/синтаксис? Или проблема в преобразовании 2to3 - возможно, я неправильно запустил инструмент. (Я имею в виду запустить как можно больше фиксеров)


person Matthew Stamy    schedule 05.12.2013    source источник


Ответы (1)


Я не знаю точно, но я предполагаю, что это жертва новой обработки Unicode в 3.x:

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

Однако для этого вы можете использовать двоичный ввод-вывод:

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
person dstromberg    schedule 05.12.2013
comment
Спасибо! В конце концов, я хотел бы, чтобы мой проект (в настоящее время совместимый только с Python 2.x) был совместим с версиями Python 2.6 и выше... просто ищу лучший способ сделать это. - person Matthew Stamy; 10.12.2013