Pythonの機能のようなsprintf


131

多くの処理、フォーマット、および最後sprintfにPythonのCスタイルの機能を使用してテキストファイルにバッファーを書き込む文字列バッファーを作成したいと思います。条件ステートメントのため、直接ファイルに書き込むことはできません。

例:擬似コード:

sprintf(buf,"A = %d\n , B= %s\n",A,B)
/* some processing */
sprint(buf,"C=%d\n",c)
....
...
fprintf(file,buf)

したがって、出力ファイルには次の種類のo / pがあります。

A= foo B= bar
C= ded
etc...

編集、私の質問を明確にするために:
buf大きなバッファーには、sprintfを使用してフォーマットされたこれらのすべての文字列が含まれています。あなたの例でbufは、古い値ではなく、現在の値のみが含まれます。例えば、最初にbufI書いたA= something ,B= something後にC= something同じに追加されましたbufが、あなたのPythonの答えにbuf私が欲しい-私は望んでいないときだけ最後の値を、含まれているbufすべて持っているprintfと同じように、私は、初めから行っていますよC


1
これは、Cでsprintf()が機能する方法とは異なります(内容はの最後でbufはなく、最初に書き込まれます)。文字列の配列を使用してから、ファイルに書き込む前にそれらを結合するのが最も効果的です。
yam655 2013

@dividebyzero一般的なプログラミング言語であるため、これはPythonでは簡単ではありませんか?たとえば、Michael J. Barberのソリューション(コメントの後に投稿)を参照してください。 def sprintf(buf, fmt, *args): ...
jdk1.0

@ jdk1.0意味がわからない、私は若くて世間知らずのPythonプログラマでした...このバッファの再利用はそれほど単純ではないため、この質問は実際には奇妙です。それぞれのsprintf呼び出し、そしてこの種のことは、Pythonを実行している場合に心配する必要のあるものではありません。とにかく、私はScalaに移り、今度はJuliaに移ってよかったです。
dividebyzero

回答:


169

Pythonには%このための演算子があります。

>>> a = 5
>>> b = "hello"
>>> buf = "A = %d\n , B = %s\n" % (a, b)
>>> print buf
A = 5
 , B = hello

>>> c = 10
>>> buf = "C = %d\n" % c
>>> print buf
C = 10

サポートされているすべてのフォーマット指定子については、このリファレンスを参照してください。

あなたも使うことができますformat

>>> print "This is the {}th tome of {}".format(5, "knowledge")
This is the 5th tome of knowledge

40

私があなたの質問を正しく理解している場合、format()そのミニ言語とともに探しているものです。

Python 2.7以降の愚かな例:

>>> print "{} ...\r\n {}!".format("Hello", "world")
Hello ...
 world!

以前のpythonバージョンの場合:(2.6.2でテスト済み)

>>> print "{0} ...\r\n {1}!".format("Hello", "world")
Hello ...
 world!

4
おそらく、たとえば、あなたがする必要がある、そのバージョンのみのPython 3でのPython 2.6で動作することに注意してください:"{0} ...\r\n {1}!".format("Hello", "world")
マーク・Longair

1
それを含めるために私の回答を編集します。ただし、Python 2.7でも機能するわけではありません。
Nicolas Lefebvre 2011年

20

私があなたの目標を理解していることを完全に確信しているわけではありませんが、StringIOインスタンスをバッファとして使用できます:

>>> import StringIO 
>>> buf = StringIO.StringIO()
>>> buf.write("A = %d, B = %s\n" % (3, "bar"))
>>> buf.write("C=%d\n" % 5)
>>> print(buf.getvalue())
A = 3, B = bar
C=5

とは異なりsprintf、文字列をbuf.writeに渡して、%演算子またはformat文字列のメソッドでフォーマットします。

もちろん、sprintf希望するインターフェイスを取得する関数を定義することもできます。

def sprintf(buf, fmt, *args):
    buf.write(fmt % args)

これは次のように使用されます:

>>> buf = StringIO.StringIO()
>>> sprintf(buf, "A = %d, B = %s\n", 3, "foo")
>>> sprintf(buf, "C = %d\n", 5)
>>> print(buf.getvalue())
A = 3, B = foo
C = 5

2
文字列フォーマット演算子(%)で* argsを使用する方法を示すための+1。
Curtis Yallop、2014年

io.StringIO()代わりにPython3を使用する
Wolf


11

文字列フォーマットを使用できます:

>>> a=42
>>> b="bar"
>>> "The number is %d and the word is %s" % (a,b)
'The number is 42 and the word is bar'

ただし、これはPython 3では削除されており、「str.format()」を使用する必要があります。

>>> a=42
>>> b="bar"
>>> "The number is {0} and the word is {1}".format(a,b)
'The number is 42 and the word is bar'

4
間違っています。Python3では削除されていません。Python3.0では3.1で廃止される予定ですが、実際には起こらなかったと思います。使用format()することをお%勧めしますが、フォーマットはまだ存在しています。(非推奨にならなかった理由については、mail.python.org / pipermail / python-dev / 2009-September / 092399.htmlを参照してください)
Duncan

1
@ダンカン; ありがとう、私はそれを知りませんでした。私はどこかでそれを非難し、二度と試しませんでした:)
utdemir

7

非常に長い文字列に挿入するには、適切な位置にあることを期待するのではなく、さまざまな引数に名前を使用すると便利です。これにより、複数の繰り返しを簡単に置き換えることもできます。

>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
'Coordinates: 37.24N, -115.81W'

他のすべての関連する回答も表示されている形式の例からの引用Format


3

これはおそらく、CコードからPythonコードへの最も近い変換です。

A = 1
B = "hello"
buf = "A = %d\n , B= %s\n" % (A, B)

c = 2
buf += "C=%d\n" % c

f = open('output.txt', 'w')
print >> f, c
f.close()

%Python の演算子は、Cの演算子とほとんど同じですsprintf。文字列をファイルに直接出力することもできます。これらの文字列形式の文字列レットが多数含まれている場合は、StringIOオブジェクトを使用して処理時間を短縮することをお勧めします。

したがって、の代わりに+=、次のようにします。

import cStringIO
buf = cStringIO.StringIO()

...

print >> buf, "A = %d\n , B= %s\n" % (A, B)

...

print >> buf, "C=%d\n" % c

...

print >> f, buf.getvalue()

3

python3 print関数のようなものを文字列にしたい場合:

def sprint(*args, **kwargs):
    sio = io.StringIO()
    print(*args, **kwargs, file=sio)
    return sio.getvalue()
>>> x = sprint('abc', 10, ['one', 'two'], {'a': 1, 'b': 2}, {1, 2, 3})
>>> x
"abc 10 ['one', 'two'] {'a': 1, 'b': 2} {1, 2, 3}\n"

または'\n'末尾になし:

def sprint(*args, end='', **kwargs):
    sio = io.StringIO()
    print(*args, **kwargs, end=end, file=sio)
    return sio.getvalue()
>>> x = sprint('abc', 10, ['one', 'two'], {'a': 1, 'b': 2}, {1, 2, 3})
>>> x
"abc 10 ['one', 'two'] {'a': 1, 'b': 2} {1, 2, 3}"

1

何かのようなもの...

greetings = 'Hello {name}'.format(name = 'John')

Hello John

これは文字列ではなくコンソールに文字列を出力します。これはOPが必要とするものです。
Teemu Leisti

これにより、画面に%sも出力されましたが、これは予期されていませんでした。しかし、私はコンマで複数の変数を追加できるのが好きです。
b01


0

2つのアプローチは、文字列バッファに書き込むか、リストに行を書き込んで後で結合することです。私はこのStringIOアプローチはもっとpythonic だと思いますが、Python 2.6以前は機能しませんでした。

from io import StringIO

with StringIO() as s:
   print("Hello", file=s)
   print("Goodbye", file=s)
   # And later...
   with open('myfile', 'w') as f:
       f.write(s.getvalue())

ContextManangers = StringIO())なしで使用することもできます。現在、私はprint関数を持つコンテキストマネージャークラスを使用しています。このフラグメントは、デバッグまたは奇妙なページング要件を挿入するのに役立つ場合があります。

class Report:
    ... usual init/enter/exit
    def print(self, *args, **kwargs):
        with StringIO() as s:
            print(*args, **kwargs, file=s)
            out = s.getvalue()
        ... stuff with out

with Report() as r:
   r.print(f"This is {datetime.date.today()}!", 'Yikes!', end=':')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.