У меня есть некоторые проблемы с последовательностью печати Python 3 по умолчанию при вложении функции печати, которую можно упростить, как в следующем примере:
>>> def print2():
... print('print2')
...
>>> print('print1', print2())
print2
print1 None
Но используя эквивалент в Python 2:
>>> def print2():
... print 'print2'
...
>>> print 'print1', print2()
print1 print2
None
Почему последовательность печати обратная? И как я могу получить естественную последовательность в Python 3 (такую же, как в Python 2), а не наоборот?
Вместо этого вы используете наверное, используя print 'print1', print2()
в Python2, обратите внимание на отсутствие круглых скобок. И разница в том, что print
— это оператор в Python 2, который обрабатывает каждый компонент отдельно.
@Martijn Pieters, спасибо за правильность, вы поняли! Итак, как я могу получить естественный результат последовательности в Python3?
@Huan Опять же, печать внутри вызова для печати довольно странная. Вместо того, чтобы пытаться изменить порядок, было бы лучше не злоупотреблять печатью, а вместо этого передавать данные и печатать их, когда это необходимо.
Разница заключается в том, что в Python 2 print
— это утверждение. Его особенность в том, что несколько выражений оцениваются слева направо, а их результат записывается сразу.
Из print
справочная документация:
Таким образом, в Python 2 оператор print 'print1', print2()
сначала оценивает 'print1'
, записывает его, затем оценивает print2()
, который сам использует print
для записи 'print2'
, а затем записывает новую строку в конце. Затем интерактивный интерпретатор Python повторяет возвращаемое значение последнего выражения, которым было None
.
В Python 3 print()
— это встроенный функция. Функции — это просто дополнительные выражения. Вы не можете выполнить функцию, пока не будут вычислены все выражения аргументов. Это означает, что print(...)
на самом деле не выполняется до тех пор, пока все его аргументы не будут оценены, и поэтому не может ничего выводить на ваш экран, пока функция print2()
не завершится и не вернет свое значение.
Таким образом, чтобы print('print1', print2())
работал, Python сначала должен оценить 'print1'
(создать строковый объект), затем оценить print2()
(вызвать print('print2')
и вернуть None
), прежде чем функция сможет быть выполнена и записать print1 None
.
Вы бы получили те же результаты в Python 2, если бы использовали print('print1', print2())
, потому что тогда вы фактически сначала создали бы кортеж с двумя элементами, а затем распечатали; print
по-прежнему является оператором, и ('print1', print2())
оценивается как ('print1', None)
(и print2
записывается на экран), прежде чем этот кортеж будет преобразован в строку и записан. Или вы можете использовать from __future__ import print_function
в Python 2, после чего компилятор отключит оператор print
, и вы также сможете использовать функцию print()
в Python 2.
Решение состоит в том, чтобы использовать два вызова функции отдельныйprint()
и заменить обычно написанную новую строку пробелом:
print('print1', end=' ')
print(print2())
Таким образом, 'print1'
будет записано на ваш экран до того, как print2()
нужно будет вызвать. Выше будет вывод
print1 print2
None
но в интерактивном интерпретаторе отсутствие новой строки немного испортило бы вывод:
>>> print('print1', end=' ')
print1 >>> print(print2())
print2
None
Но вы действительно не стали бы хочу использовать print()
для записи возвращаемого значения print2()
, которое есть None
. Удаление лишнего print()
оставит это без внимания:
print('print1', end=' ')
print2()
Если print2()
отвечает за печать, не дублируйте вызовы печати.
Однако вариант Лучший относится к не печатать внутри print2()
. Держите печать в центре внимания, и порядок больше не имеет большого значения. Вместо этого ваши функции возвращают строку для печати:
def result2():
return 'print2'
print('print1', result2())
Приведенное выше выведет print1 print2
как в Python 2 (при условии, что вы используете оператор print
, поэтому print 'print1', result2()
), так и в Python 3.
Спасибо за ваш ответ, но оператор return завершит вложение… Я опубликовал свой реальный код, посмотрите!
@Huan: в этом нет необходимости; ваш вопрос был в порядке без него. Я дал несколько советов о том, как структурировать код, вам не нужно подробно следовать ему.
@Huan: хитрость в том, чтобы не использовать печать, но чтобы собрать вещи, которые вам нужно распечатать, в список или аналогичную структуру. В конце объедините список в одну строку, верните ее и распечатайте.
@Huan: для этого примера мой совет остается в силе, см. gist.github.com/mjpieters/77e635326d2c9957faefc0dc6277b81f
Спасибо за ваше решение, какой я новичок! То есть нет возможности использовать функцию печати непосредственно в этом коде, так как в Python 3 последовательность печати всегда обратная?
Неа. Конечно, вы можете использовать print(part1, end=' ')
, а затем print(part2())
для управления порядком, но здесь это не лучший вариант, потому что ваши рекурсивные вызовы функций смешивают печать и возврат значений для печати. В итоге вы печатаете много дополнительных значений None
. Проблема в том, как устроен этот код, а не в print()
, на самом деле.
Почему вы печатаете вместо возврата строки? Аргументы функций оцениваются до того, как будет выполнена функция, так что это ожидаемое и правильное поведение.