在 Python 中类似 sprintf 的功能

我想要创建一个字符串缓冲区来进行大量的处理、格式化并最终使用 Python 中的 C 风格 sprintf功能在文本文件中写入缓冲区。由于条件语句的原因,我无法将它们直接写入文件。

例如伪代码:

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中一样。

341407 次浏览

如果我正确理解你的问题,格式()是你正在寻找的,随着 它的迷你语言

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!

使用 格式化操作符 %:

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

可以使用字符串格式设置:

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

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

这可能是从 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()

要插入到一个非常长的字符串中,最好使用不同参数的名称,而不是希望它们处于正确的位置。这也使得替换多个递归变得更加容易。

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

摘自 格式示例,其中还显示了所有其他与 Format相关的答案。

我不能完全确定我理解您的目标,但是您可以使用 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

比如..。

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


Hello John

如果你想要一个 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}"

两种方法是写入字符串缓冲区或写入行到列表中,然后将它们联接起来。我认为 StringIO方法更像 Python,但是在 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())

您也可以在没有 ContextMananger(s = 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=':')

我知道这是一个老线程-但有一个新的字符串插值“样式”-f”字符串格式构造。

a = 5
b = "hello"
buf = f"A = {a:d}\n , B = {b}\n"

PEP-498中指定了 F-String (它的名称)。

在学习 F-String 之前,我会调用这样的格式:

a = 5
b = "hello"
buf = "A = {a:d}\n , B = {b}\n".format( **{ **globals() , **locals() } )

根据 PEP-498文档,F-String 可用于 Python 3.6或更高版本。