为什么printf()在Python中给出一个奇怪的输出?
我试图在Linux的python命令行中使用C函数printf()
。 为了做到这一点,我导入了ctypes
。 我的问题是:如果我创build一个CDLL
对象在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 >>>
我无法猜测是什么原因导致这种行为
如果有问题,我在Linux上使用Python 2.7.6。
编辑:
Python版本/操作系统对此没有影响。 有关详细信息,请参阅下面的PM 2Ring的答案。 在Windows上,只需将libc = ctypes.CDLL("msvcrt.dll")
的初始化更改为libc = ctypes.CDLL("msvcrt.dll")
,其中.dll
是可选的。 另一种获得正确输出的方式比调用函数的方法是将printf()
的返回值存储在一个variables中:
>>> import ctypes >>> libc = ctypes.CDLL("libc.so.6") # "mscvrt.dll" on windows >>> for i in range(10): ... r = libc.printf("%d", i) ... 0123456789>>>
我仍然更喜欢这个function,因为你可以更容易地添加结束的换行符。
每个数字末尾的那些额外的'1'
是来自printf
的返回值,它返回它打印的字符数。 交互式解释器中调用的函数的返回值会自动打印(除非是None
)。
事实上,交互式解释器打印任何未分配的非None
expression式。 当然,它为这些expression式添加了一个换行符,这就解释了为什么第一个代码块中的输出是在不同的行上。
你的pr
函数没有return语句,所以它返回None
,因此没有额外的东西被打印出来。
虽然PM 2Ring已经很好地回答了这个问题,但是我认为值得指出的是,printf的行为或者非常接近的东西可以作为一个python内置的,所以真的很奇怪你会使用C库版本,除非你用它来学习如何使用ctypes
,在这种情况下继续。
但是另一方面,当你没有使用足够的python来知道REPL是如何工作的时候想要使用ctypes
是很奇怪的…冒着傲慢的风险,像有10年python经验的人,我从来没有实际上不得不使用ctypes
呢。
在Python中有两个内置的string格式选项:
print("%d" % (i,))
这是旧的风格,和printf非常相似
print("{:d}".format(i))
这是python 3的新function,而且更强大一些。 有问题解决这个网站上的差异。 上述两行都将输出与libc.printf("%d\n", i)
。 也可以不使用换行符进行打印 。
“%”string格式的CPython实现实际上使用了sprintf。