Как исправить печать (((двойные скобки) после преобразования в 2to3? - PullRequest
0 голосов
/ 07 апреля 2019

При переносе моего проекта в Python 3 (2to3-3.7 -w -f print *) я заметил, что операторы lot (но не все) print стали print ((...)), поэтому эти операторы теперь печатают кортежи вместо выполнения ожидаемого поведения. Я понял, что если бы я использовал -p, я бы сейчас был в лучшем положении, потому что from __future__ import print_function находится наверху каждого затронутого модуля.

Я думаю о том, чтобы попытаться использовать sed, чтобы исправить это, но прежде чем сломать зубы, я подумал, что увижу, сталкивался ли кто-нибудь еще с этим раньше. Есть ли функция 2to3, чтобы убрать это?

Я делаю , использую контроль версий (git) и получаю коммиты непосредственно до и после (а также файлы .bak, которые создает 2to3), но я не уверен, как изолировать изменения, которые я сделано из ситуаций печати. ​​

Ответы [ 2 ]

2 голосов
/ 07 апреля 2019

Вы уже печатали кортежи. Если бы вы не были, то и вас нет сейчас.

Чтобы проиллюстрировать, ваш код должен был бы использовать print, как если бы это была функция:

# Python 2
print(somestring)

который становится после перевода

# Python 3
print((somestring))

Это не кортеж, это , просто пара скобок. Это приводит к одинаковому выводу на любой версии. На самом деле, 2to3 достаточно умен, чтобы снова убрать внутренние скобки; фактический результат написан просто

# Python 3
print(somestring)

Однако, если вы использовали несколько аргументов в Python 2:

# Python 2
print(arg1, arg2)

тогда вы уже печатаете кортеж, потому что это действительно:

value_to_print = (arg1, arg2)
print value_to_print

Так что было бы правильно сохранить это поведение в Python 3. Если вы видите, что инструмент 2to3 использует print((....)), то он определил, что вы уже печатали кортежи.

Демо-версия:

$ cat testprint.py
print('not a tuple')
print('two-value', 'tuple')
$ python2.7 testprint.py
not a tuple
('two-value', 'tuple')
$ 2to3 -w -f print testprint.py
RefactoringTool: Refactored testprint.py
--- testprint.py    (original)
+++ testprint.py    (refactored)
@@ -1,2 +1,2 @@
 print('not a tuple')
-print('two-value', 'tuple')
+print(('two-value', 'tuple'))
RefactoringTool: Files that were modified:
RefactoringTool: testprint.py
$ python3.7 testprint.py
not a tuple
('two-value', 'tuple')

Обратите внимание, что это отличается от использования from __future__ import print_function в вашем коде Python 2, чтобы отключить оператор print и, таким образом, заставить код вызывать встроенную функцию print() . Инструмент 2to3 уже обнаруживает этот случай и будет проходить через print(...) вызовы функций без изменений:

$ cat futureprint.py
from __future__ import print_function
print('not', 'a tuple')
$ python2.7 futureprint.py
not a tuple
$ 2to3 -w -f print futureprint.py
RefactoringTool: No files need to be modified.
$ python3.7 futureprint.py
not a tuple

Вы можете заставить 2to3 предполагать, что все ваши файлы используют from __future__ import print_function, независимо от этого, с помощью ключа командной строки -p / --print-function:

-p, --print-function  Modify the grammar so that print() is a function

Тем не менее, любые преднамеренные print (tuple_element1, tuple_element2, ...) операторы печати будут неверно переведены как вызовы функций:

$ cat printtuple.py
print ('two-value', 'tuple')
$ python2.7 printtuple.py
('two-value', 'tuple')
$ 2to3 -w -f print -p printtuple.py
RefactoringTool: No files need to be modified.
$ python3.7 printtuple.py
two-value tuple
0 голосов
/ 07 апреля 2019

Попробуйте использовать флаг -p. Смотрите последнюю заметку здесь .

Когда передается -p, 2to3 обрабатывает печать как функцию, а не как оператор. Это полезно, когда используется from __future__ import print_function. Если этот параметр не указан, средство исправления печати будет заключать вызовы печати в дополнительный набор скобок, поскольку он не может различить оператор печати с круглыми скобками (например, print ("a" + "b" + "c")) и истинный вызов функции.

...