LinuxのpythonコマンドラインでC関数printf()
を使用しようとしました。それを機能させるために、ctypes
をインポートしました。私の問題は次のとおりです。 CDLL
のオブジェクトを作成して、ループでprintf()
- functionを使用すると、非常に奇妙な出力が得られます。
_>>> 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で問題があれば)を使用しています。
編集:
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'
sは、printf
からの戻り値であり、印刷する文字数を返します。インタラクティブインタープリターで呼び出された関数の戻り値は自動的に出力されます(None
でない限り)。
実際、インタラクティブインタープリターは、割り当てられていない非None
式を出力します。そしてもちろん、これらの式に改行が追加され、最初のコードブロックの出力が別の行にある理由が説明されます。
pr
関数にはreturnステートメントがないため、None
を返すため、余分なものは出力されません。
PM 2Ringはこの質問に非常によく答えていますが、printfの動作、または非常に近いものがpython built-なので、ctypes
の使用方法を学ぶために使用しない限り、Cライブラリバージョンを使用するのは非常に奇妙です。
しかし一方で、十分なpythonを使用してREPLがどのように機能するかを理解していないときにctypes
を使用したいのは奇妙です。 ... years慢に聞こえるかもしれませんが、10年の経験があるpythonの経験があるので、実際にctypes
を使う必要はありませんでした。
Pythonの文字列フォーマットには、2つの組み込みオプションがあります。
_print("%d" % (i,))
_
これは古いスタイルで、printfと非常によく似ています。
_print("{:d}".format(i))
_
これはpython 3の新機能であり、やや強力です。このサイトの違いに対処する questions があります。上記の両方の行はlibc.printf("%d\n", i)
。 改行なしで印刷 も可能です。
「%」文字列フォーマットのCPython実装では、実際にはsprintf 内部 を使用します。