Ich möchte einen Zeichenkettenpuffer erstellen, um viele Verarbeitungsschritte auszuführen, den Puffer zu formatieren und schließlich in eine Textdatei zu schreiben, wobei eine sprintf
-Funktionalität im C-Stil in Python verwendet wird. Aufgrund von Bedingungsanweisungen kann ich sie nicht direkt in die Datei schreiben.
z.B. Pseudo-Code:
sprintf(buf,"A = %d\n , B= %s\n",A,B)
/* some processing */
sprint(buf,"C=%d\n",c)
....
...
fprintf(file,buf)
In der Ausgabedatei haben wir also diese Art von O/P:
A= foo B= bar
C= ded
etc...
Bearbeiten, um meine Frage zu klären: buf
ist ein großer Puffer, der alle diese Zeichenfolgen enthält, die mit sprintf ..__ formatiert wurden. Nach Ihren Beispielen enthält buf
nur die aktuellen Werte, nicht ältere . ZB zuerst in buf
Ich schrieb A= something ,B= something
später C= something
wurde in derselben buf
angehängt, aber in Ihren Python-Antworten enthält buf
nur den letzten Wert, den ich nicht möchte - ich möchte, dass buf
alle printf
s hat, die ich seit dem Anfang gemacht habe, wie in C
.
Python hat dafür einen %
-Operator.
>>> 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
Diese reference enthält alle unterstützten Formatangaben.
Sie könnten auch format
verwenden:
>>> print "This is the {}th tome of {}".format(5, "knowledge")
This is the 5th tome of knowledge
Wenn ich Ihre Frage richtig verstanden habe, ist format () was Sie suchen, zusammen mit seiner Minisprache .
Dummes Beispiel für Python 2.7 und höher:
>>> print "{} ...\r\n {}!".format("Hello", "world")
Hello ...
world!
Für frühere Python-Versionen: (getestet mit 2.6.2)
>>> print "{0} ...\r\n {1}!".format("Hello", "world")
Hello ...
world!
Ich bin nicht ganz sicher, ob ich Ihr Ziel verstehe, aber Sie können eine StringIO
-Instanz als Puffer verwenden:
>>> 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
Im Gegensatz zu sprintf
übergeben Sie einfach einen String an buf.write
und formatieren ihn mit dem %
-Operator oder der format
-Methode von Zeichenfolgen.
Sie können natürlich eine Funktion definieren, um die sprintf
-Schnittstelle zu erhalten, auf die Sie hoffen:
def sprintf(buf, fmt, *args):
buf.write(fmt % args)
was würde so verwendet werden:
>>> 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
Verwenden Sie den Formatierungsoperator %
:
buf = "A = %d\n , B= %s\n" % (a, b)
print >>f, buf
Sie können die String-Formatierung verwenden:
>>> a=42
>>> b="bar"
>>> "The number is %d and the Word is %s" % (a,b)
'The number is 42 and the Word is bar'
Dies wird jedoch in Python 3 entfernt. Sie sollten "str.format ()" verwenden:
>>> 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'
Zum Einfügen in eine sehr lange Zeichenfolge ist es nett, Namen für die verschiedenen Argumente zu verwenden, anstatt zu hoffen, dass sie an den richtigen Positionen stehen. Dies erleichtert auch das Ersetzen mehrerer Wiederholungen.
>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W')
'Coordinates: 37.24N, -115.81W'
Aus Formatbeispielen entnommen , wobei auch alle anderen Format
-bezogenen Antworten angezeigt werden.
Dies ist wahrscheinlich die engste Übersetzung aus Ihrem C-Code in Python-Code.
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()
Der %
-Operator in Python macht fast genau dasselbe wie die sprintf
von C. Sie können die Zeichenfolge auch direkt in eine Datei drucken. Wenn viele dieser String-formatierten Stringlets beteiligt sind, empfiehlt es sich, ein StringIO
-Objekt zu verwenden, um die Verarbeitungszeit zu verkürzen.
Statt +=
zu tun, machen Sie folgendes:
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()
Wenn Sie etwas wie die Python3-Druckfunktion wollen, aber auf einen String:
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"
oder ohne den '\n'
am ende:
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}"
Schauen Sie sich "Literal String Interpolation" an https://www.python.org/dev/peps/pep-0498/
Ich fand es durch die http://www.malemburg.com/
Nach diesem Leistungsvergleich ist List Comprehensions die schnellste Option. Hier ist eine objektorientierte Implementierung, die die in Python 3.6 eingeführte Literal String Interpolation (auch als f-String bezeichnet) verwendet:
class Buffer:
_buf = []
def sprintf(self,s):
self._buf.append(s)
def fprintf(self,filename):
with open(filename,'w+') as file:
file.write(''.join([self._buf[i] for i in range(len(self._buf)) ]))
def testBuffer():
A = 1
B = "Hello"
C = "World"
buf = Buffer()
buf.sprintf("A = {A}\n , B = {B}\n")
buf.sprintf("C = {C}\n")
buf.fprintf("output.txt")
testBuffer()
So etwas wie...
name = "John"
print("Hello %s", name)
Hello John