Chciałbym stworzyć bufor ciągów do wielu operacji przetwarzania, formatowania i na koniec zapisywania bufora w pliku tekstowym przy użyciu sprintf
funkcji w stylu C w Pythonie. Z powodu instrukcji warunkowych nie mogę zapisać ich bezpośrednio do pliku.
np. pseudokod:
sprintf(buf,"A = %d\n , B= %s\n",A,B)
/* some processing */
sprint(buf,"C=%d\n",c)
....
...
fprintf(file,buf)
Więc w pliku wyjściowym mamy tego rodzaju o / p:
A= foo B= bar
C= ded
etc...
Edytuj, żeby wyjaśnić moje pytanie:
buf
czy duży bufor zawiera wszystkie te ciągi, które zostały sformatowane przy użyciu sprintf. Idąc za swoimi przykładami, buf
będą zawierały tylko aktualne wartości, a nie starsze. np. pierwszy w, buf
który napisałem A= something ,B= something
później, C= something
był dodawany w tym samym buf
, ale w twoim Pythonie odpowiedzi buf
zawierają tylko ostatnią wartość, której nie chcę - chcę buf
mieć wszystkie printf
s, które zrobiłem od początku, jak w C
.
buf
, a nie na końcu). Prawdopodobnie najlepiej byłoby użyć tablicy ciągów, a następnie połączyć je ze sobą przed zapisaniem do pliku.def sprintf(buf, fmt, *args): ...
Odpowiedzi:
Python ma
%
do tego 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
Zobacz tę dokumentację dla wszystkich obsługiwanych specyfikatorów formatu.
Równie dobrze możesz użyć
format
:>>> print "This is the {}th tome of {}".format(5, "knowledge") This is the 5th tome of knowledge
źródło
Jeśli dobrze rozumiem twoje pytanie, format () jest tym, czego szukasz, wraz z jego mini językiem .
Głupi przykład dla Pythona 2.7 i nowszych:
>>> print "{} ...\r\n {}!".format("Hello", "world") Hello ... world!
W przypadku wcześniejszych wersji Pythona: (testowane z 2.6.2)
>>> print "{0} ...\r\n {1}!".format("Hello", "world") Hello ... world!
źródło
"{0} ...\r\n {1}!".format("Hello", "world")
Nie jestem do końca pewien, czy rozumiem Twój cel, ale możesz użyć
StringIO
instancji jako bufora:>>> 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
W przeciwieństwie do tego
sprintf
, po prostu przekazujesz ciągbuf.write
, formatując go za pomocą%
operatora lubformat
metody łańcuchów.Możesz oczywiście zdefiniować funkcję, aby uzyskać
sprintf
interfejs, na który masz nadzieję:def sprintf(buf, fmt, *args): buf.write(fmt % args)
który zostałby użyty w ten sposób:
>>> 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
źródło
io.StringIO()
zamiast tego użyj Pythona3Użyj operatora formatowania
%
:buf = "A = %d\n , B= %s\n" % (a, b) print >>f, buf
źródło
Możesz użyć formatowania ciągów:
>>> a=42 >>> b="bar" >>> "The number is %d and the word is %s" % (a,b) 'The number is 42 and the word is bar'
Ale to zostało usunięte w Pythonie 3, powinieneś użyć "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'
źródło
format()
może być lepsze, ale%
formatowanie nadal istnieje. (Zobacz mail.python.org/pipermail/python-dev/2009-September/092399.html, aby zapoznać się z niektórymi powodami, dla których nie został wycofany)Aby wstawić do bardzo długiego ciągu, dobrze jest użyć nazw dla różnych argumentów, zamiast mieć nadzieję, że znajdują się one we właściwych miejscach. Ułatwia to również zastąpienie wielu powtórzeń.
>>> 'Coordinates: {latitude}, {longitude}'.format(latitude='37.24N', longitude='-115.81W') 'Coordinates: 37.24N, -115.81W'
Zaczerpnięte z przykładów formatu , w których
Format
pokazane są również wszystkie inne powiązane odpowiedzi.źródło
Jeśli chcesz czegoś takiego jak funkcja print python3, ale do łańcucha:
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"
lub bez
'\n'
na końcu: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}"
źródło
Jest to prawdopodobnie najbliższe tłumaczenie twojego kodu C na kod Pythona.
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()
%
Operator w Pythonie robi prawie dokładnie tak samo jak C użytkownikasprintf
. Możesz również wydrukować ciąg bezpośrednio do pliku. Jeśli zaangażowanych jest wiele stringletów sformatowanych jako ciągi znaków, rozsądne może być użycieStringIO
obiektu w celu przyspieszenia czasu przetwarzania.Więc zamiast robić
+=
, zrób to: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()
źródło
Coś jak...
greetings = 'Hello {name}'.format(name = 'John') Hello John
źródło
Spójrz na „Literal String Interpolation” https://www.python.org/dev/peps/pep-0498/
Znalazłem to przez http://www.malemburg.com/
źródło
Dwa podejścia to zapisywanie w buforze łańcuchów lub zapisywanie wierszy do listy i dołączanie do nich później. Myślę, że
StringIO
podejście jest bardziej pythonowe, ale nie działało przed wersją 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())
Możesz ich również używać bez
ContextMananger
(s = StringIO()
). Obecnie używam klasy menedżera kontekstu zprint
funkcją. Ten fragment może być przydatny, aby móc wstawić debugowanie lub dziwne wymagania dotyczące stronicowania: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=':')
źródło