Sprintf как функциональность в Python

Я хотел бы создать строковый буфер, чтобы сделать много обработки, форматировать и, наконец, написать буфер в текстовом файле, используя функциональность C-style sprintf в Python. Из-за условных операторов я не могу записать их непосредственно в файл.

например, псевдокод:

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 будет содержать только текущие значения, а не старые. например, сначала в buf Я написал A= something ,B= something позже C= something был добавлен в тот же самый buf, но в ответах на Python buf содержит только последнее значение, которое мне не нужно - я хочу, чтобы buf имел все printf, которые я сделал с самого начала, как в C.

Ответ 1

Для этого у 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

Ответ 2

Если я правильно понял ваш вопрос, 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!

Ответ 3

Я не совсем уверен, что понимаю вашу цель, но вы можете использовать экземпляр 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

Ответ 4

Используйте оператор форматирования %:

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

Ответ 5

Вы можете использовать форматирование строк:

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

Ответ 6

Для вставки в очень длинную строку полезно использовать имена для разных аргументов, вместо того, чтобы надеяться, что они находятся в правильных позициях. Это также облегчает замену нескольких повторений.

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

Взято из примеров форматов, где также показаны все остальные ответы Format -related.

Ответ 7

Это, вероятно, самый близкий перевод от вашего кода на код 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()

Ответ 9

Согласно (это сравнение производительности), List List понимает ваш самый быстрый вариант. Вот объектно-ориентированная реализация, которая использует Literal String Interpolation (также называемую f-String), введенную в python 3.6:


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

Ответ 10

Что-то вроде...

name = "John"

print("Hello %s", name)

Hello John

Ответ 11

Если вы хотите что-то вроде функции печати python3, но в строку:

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