Почему printf() дает странный вывод в python?
Я попытался использовать C-функцию printf()
в командной строке python в Linux. Чтобы выполнить эту работу, я импортировал ctypes
. Моя проблема: если я создаю объект CDLL
для использования printf()
-функции в цикле, я получаю действительно странный вывод:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6")
>>> for i in range(10):
... libc.printf("%d", i)
...
01
11
21
31
41
51
61
71
81
91
>>>
Однако, когда я вызываю этот цикл внутри функции, он работает как ожидалось:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6")
>>> def pr():
... for i in range(10):
... libc.printf("%d", i)
... libc.printf("\n")
...
>>> pr()
0123456789
>>>
Я не могу догадаться, что вызывает такое поведение...
Я использую Python 2.7.6 для Linux, если это имеет значение.
EDIT:
Версия Python/операционная система не влияет на это. См. Ниже приведенный комментарий PM 2Ring. В Windows вам нужно изменить инициализацию libc
на libc = ctypes.CDLL("msvcrt.dll")
, где .dll
является необязательным. Другой способ получить правильный результат, чем вызов функции, - сохранить возвращаемое значение printf()
в переменной:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6") # "mscvrt.dll" on windows
>>> for i in range(10):
... r = libc.printf("%d", i)
...
0123456789>>>
Я по-прежнему предпочитаю эту функцию, потому что вы можете добавить завершающую линейку.
Ответы
Ответ 1
Эти дополнительные '1'
в конце каждого числа - это возвращаемое значение из printf
, которое возвращает количество символов, которые он печатает. Возвращаемое значение функции, вызываемой в интерактивном интерпретаторе, автоматически печатается (если только None
).
Фактически, интерактивный интерпретатор печатает любое выражение не None
, которое не назначено. И, конечно же, он добавляет новую строку в эти выражения, что объясняет, почему вывод в вашем первом блоке кода находится в отдельных строках.
В вашей функции pr
нет оператора return, поэтому он возвращает None
, и, таким образом, никакие дополнительные материалы не будут напечатаны.
Ответ 2
В то время как PM 2Ring ответил на вопрос достаточно хорошо, я считаю, что стоит отметить, что поведение printf или что-то очень близкое, доступно как встроенный python, поэтому очень странно, что вы будете использовать C версию библиотеки, если вы не используете ее, чтобы узнать, как использовать ctypes
, и в этом случае продолжить.
Но, с другой стороны, странно хотеть использовать ctypes
, когда вы не использовали достаточно питона для того, чтобы знать, как работает REPL... рискует казаться высокомерным, как человек с 10-летним опытом питона, Мне никогда не приходилось использовать ctypes
.
Есть два встроенных параметра форматирования строк в python:
print("%d" % (i,))
который является старым стилем и очень похож на printf, и
print("{:d}".format(i))
который является новым для python 3 и несколько более мощным. Есть questions, где рассматриваются различия на этом сайте. Обе вышеперечисленные строки будут выводиться идентично libc.printf("%d\n", i)
. Также можно печатать без новой строки.
Реализация форматирования строк "%" на CPython фактически использует sprintf под капотом.