webentwicklung-frage-antwort-db.com.de

sprintfähnliche Funktionalität in Python

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 printfs hat, die ich seit dem Anfang gemacht habe, wie in C.

105
spring

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
142
Alexei Sholik

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!
34

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
14

Verwenden Sie den Formatierungsoperator % :

buf = "A = %d\n , B= %s\n" % (a, b)
print >>f, buf
10
NPE

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'
9
utdemir

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.

6
Jost

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()
3
Y.H Wong

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}"
0
Michael

Schauen Sie sich "Literal String Interpolation" an https://www.python.org/dev/peps/pep-0498/

Ich fand es durch die http://www.malemburg.com/

0
Andrei Sura

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()
0

So etwas wie...

name = "John"

print("Hello %s", name)

Hello John
0
bmatovu