38 votes

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

J'ai essayé d'utiliser le C-fonction printf() dans le python en ligne de commande sur Linux. Pour faire ce travail, j'ai importé ctypes. Mon problème est: Si je crée un objet de CDLL utilisation de l' printf()-fonction dans une boucle, je reçois vraiment une drôle de sortie:

>>> 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 à l'intérieur d'une fonction, il 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 quelles sont les causes de ce comportement ...
Je suis à l'aide de Python 2.7.6 sur Linux si il le faut.

EDIT:

Une version de Python / système d'exploitation n'a aucune influence à ce. Voir PM 2Ring la réponse ci-dessous pour plus de détails. Sur Windows, vous n'avez qu'à changer l'initialisation de libc de libc = ctypes.CDLL("msvcrt.dll").dll est facultatif. Une autre façon d'obtenir de bons résultats de l'appel d'une fonction serait de stocker la valeur de retour de l' 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 encore la fonction, car vous pouvez ajouter un dernier saut de ligne plus facile.

85voto

PM 2Ring Points 11424

Ces extra - '1's à la fin de chaque numéro de la valeur de retour de printf, qui retourne le nombre de caractères qu'elle imprime. La valeur de retour d'une fonction appelée dans interactive interprète est automatiquement imprimé (sauf si c'est de None).

En fait, l'interactive interprète imprime tout non-None expression qui n'est pas affecté. Et bien sûr, il ajoute une nouvelle ligne à ces expressions, ce qui explique pourquoi la sortie de votre premier bloc de code est sur des lignes séparées.

Votre pr fonction n'a pas d'instruction return, elle retourne None, et donc pas de trucs supplémentaires qui sera imprimé.

5voto

Amanda Ellaway Points 78

Alors que PM 2Ring a répondu à la question très bien, je pense qu'il est important de souligner que le printf du comportement, ou quelque chose de très proche, est disponible en python intégré, donc c'est vraiment très étrange ce que vous feriez à l'aide de la version de la bibliothèque C, sauf si vous l'utilisez pour savoir comment utiliser ctypes, auquel cas procéder.

Mais d'un autre côté, il est étrange de vouloir les utiliser ctypes lorsque vous n'avez pas utilisé assez de python pour savoir comment le REPL fonctionne... au risque de paraître arrogant, comme quelqu'un avec 10 ans de python, je n'ai jamais eu à l'utiliser ctypes encore.

Il y a deux options intégrées pour la mise en forme de chaîne en python:

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

qui est l'ancien style, et très semblable à printf, et

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

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

Le Disponible de la mise en œuvre de "%" mise en forme de chaîne utilise sprintf sous le capot.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X