Pourquoi printf () donne-t-il une sortie étrange en python?

J’ai essayé d’utiliser la fonction C printf() dans la ligne de commande python sous Linux. Pour que cela fonctionne, j’ai importé des ctypes . Mon problème est le suivant: si je crée un object de CDLL pour utiliser la fonction printf() en boucle, la sortie est vraiment étrange:

 >>> 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 >>> 

Cependant, lorsque j’appelle cette boucle dans une fonction, cela fonctionne comme prévu:

 >>> import ctypes >>> libc = ctypes.CDLL("libc.so.6") >>> def pr(): ... for i in range(10): ... libc.printf("%d", i) ... libc.printf("\n") ... >>> pr() 0123456789 >>> 

Je ne peux pas deviner ce qui cause ce comportement …
J’utilise Python 2.7.6 sous Linux si c’est important.

MODIFIER:

La version / le système d’exploitation Python n’a aucune influence sur cela. Voir la réponse de PM 2Ring ci-dessous pour plus de détails. Sous Windows, il suffit de changer l’initialisation de libc pour libc = ctypes.CDLL("msvcrt.dll").dll est facultatif. Une autre façon d’obtenir la sortie correcte en appelant une fonction serait de stocker la valeur de retour de printf() dans une variable:

 >>> import ctypes >>> libc = ctypes.CDLL("libc.so.6") # "mscvrt.dll" on windows >>> for i in range(10): ... r = libc.printf("%d", i) ... 0123456789>>> 

Je préfère toujours la fonction car vous pouvez append un saut de ligne plus facile.

Ces '1' supplémentaires à la fin de chaque numéro sont la valeur de retour de printf , qui renvoie le nombre de caractères qu’elle imprime. La valeur de retour d’une fonction appelée dans l’interpréteur interactif est automatiquement imprimée (sauf s’il s’agit de None ).

En fait, l’interpréteur interactif imprime toutes les expressions non non atsortingbuées. Et bien sûr, il ajoute une nouvelle ligne à ces expressions, ce qui explique pourquoi la sortie de votre premier bloc de code se trouve sur des lignes séparées.

Votre fonction pr n’a pas de déclaration de retour, elle renvoie donc None , et donc aucun élément supplémentaire n’est imprimé.

Alors que PM 2Ring a très bien répondu à la question, je pense que cela vaut la peine de souligner que le comportement de printf, ou quelque chose de très proche, est disponible en tant que python intégré. sauf si vous l’utilisez pour apprendre à utiliser les ctypes , auquel cas continuez.

Mais d’un autre côté, il est étrange de vouloir utiliser des ctypes quand vous n’avez pas utilisé suffisamment de python pour savoir comment fonctionne la REPL … au risque de paraître arrogant, en tant que personne ayant 10 ans d’expérience en python, je n’ai jamais en fait, il fallait encore utiliser ctypes .

Il existe deux options intégrées pour le formatage des chaînes en Python:

 print("%d" % (i,)) 

qui est l’ancien style, et très similaire à printf, et

 print("{:d}".format(i)) 

ce qui est nouveau pour python 3 et qui est un peu plus puissant. Il y a des questions sur les différences sur ce site. Les deux lignes ci-dessus seront libc.printf("%d\n", i) à l’identique de libc.printf("%d\n", i) . Il est également possible d’ imprimer sans la nouvelle ligne .

L’implémentation CPython du formatage de chaîne “%” utilise en fait sprintf sous le capot .