c_int - ¿Por qué printf() da un resultado extraño en python?
ctypes python 3 (2)
Esos ''1''
adicionales al final de cada número son el valor de retorno de printf
, que devuelve la cantidad de caracteres que imprime. El valor de retorno de una función llamada en el intérprete interactivo se imprime automáticamente (a menos que sea None
).
De hecho, el intérprete interactivo imprime cualquier expresión que no sea None
que no esté asignada. Y, por supuesto, agrega una nueva línea a esas expresiones, lo que explica por qué la salida en su primer bloque de código está en líneas separadas.
Su función pr
no tiene una declaración de devolución, por lo que devuelve None
y, por lo tanto, no se imprimen cosas adicionales.
Intenté usar la función-C printf()
en la línea de comando de python en Linux. Para que funcione, ctypes
. Mi problema es: si creo un objeto de CDLL
para usar la printf()
en un bucle, obtengo un resultado realmente extraño:
>>> 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
>>>
Sin embargo, cuando llamo a este bucle dentro de una función, funciona como se esperaba:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6")
>>> def pr():
... for i in range(10):
... libc.printf("%d", i)
... libc.printf("/n")
...
>>> pr()
0123456789
>>>
No puedo adivinar qué causa este comportamiento ...
Estoy usando Python 2.7.6 en Linux si es importante.
EDITAR:
La versión Python / sistema operativo no tiene influencia en esto. Ver la respuesta de PM 2Ring a continuación para más detalles. En Windows, solo tiene que cambiar la inicialización de libc
a libc = ctypes.CDLL("msvcrt.dll")
donde .dll
es opcional. Otra forma de obtener el resultado correcto que llamar a una función sería almacenar el valor de retorno de printf()
en una variable:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6") # "mscvrt.dll" on windows
>>> for i in range(10):
... r = libc.printf("%d", i)
...
0123456789>>>
Todavía prefiero la función porque puedes agregar un final de línea concluyente más fácil.
Si bien el PM 2Ring ha respondido la pregunta bastante bien, creo que vale la pena señalar que el comportamiento de printf, o algo muy cercano, está disponible como un pitón incorporado, por lo que es realmente extraño que uses la versión de la biblioteca C, a menos que lo esté usando para aprender a usar los ctypes
, en cuyo caso continuar.
Pero, por otro lado, es extraño querer usar ctypes
cuando no has usado suficiente python para saber cómo funciona el REPL ... a riesgo de sonar arrogante, como alguien con 10 años de experiencia en python, nunca en realidad tenía que usar ctypes
todavía.
Hay dos opciones incorporadas para el formateo de cadenas en Python:
print("%d" % (i,))
que es el estilo antiguo, y muy similar a printf, y
print("{:d}".format(i))
que es nuevo para python 3, y es algo más poderoso. Hay questions abordan las diferencias en este sitio. Ambas líneas anteriores generarán un resultado idéntico a libc.printf("%d/n", i)
. También es posible imprimir sin la nueva línea .
La implementación de CPython del formato de cadena "%" realmente usa sprintf bajo el capó .