2011-03-15 97 views
87

我想创建一个字符串缓冲区来执行大量处理,格式并最终在Python中使用C风格sprintf功能将文本缓冲区写入文本文件中。由于条件语句,我不能直接将它们写入文件。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= somethingC= something在同一buf被追加,但在你的Python回答buf只包含最后一个值,这不是我想要的 - 我想buf有所有printf小号从一开始我都做了,如在C中那样。

+0

这是一个很好的问题,我认为没有回答这些问题接近解决这一点。我不想做类似“%s%s%s”%(a,b,c)的东西,我想提供一个函数参数列表并在输出中看到一个字符串。 – dividebyzero 2013-01-10 16:23:00

+1

这不是sprintf()在C中的工作方式(它在'buf'的开头写入内容,而不是在末尾)。最好使用字符串数组,然后在写入之前将它们结合在一起到文件。 – yam655 2013-05-05 02:33:53

回答

33

如果我正确理解你的问题,format()是你正在寻找,以及its mini-language

傻例如,对于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! 
+4

您应该注意到,该版本仅适用于Python 3.例如,在Python 2.6中,您需要执行:“{0} ... \ r \ n {1}!”。format(“Hello”, “world”)' – 2011-03-15 09:58:01

+1

编辑我的答案包括那个;不要说它也适用于Python 2.7! – 2011-03-15 09:59:04

+0

当然,谢谢:) – 2011-03-15 10:04:01

8

你可以使用字符串格式:

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

错误,它不会在Python 3中删除.Python 3.0表示它将在3.1中被弃用,但我相信从未发生过。使用'format()'可能更可取,但'%'格式仍然存在。 (请参阅http://mail.python.org/pipermail/python-dev/2009-September/092399.html了解为什么它不被弃用的一些原因) – Duncan 2011-03-15 14:30:47

+1

@Duncan;谢谢,我不知道。我在某个地方看过它,并且再也没有尝试过:)。 – utdemir 2011-03-16 13:38:01

122

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 

对于所有支持的格式说明符,请参阅此reference

你还可使用format

>>> print "This is the {}th tome of {}".format(5, "knowledge") 
This is the 5th tome of knowledge 
3

这可能是从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。您也可以直接将字符串打印到文件。如果涉及到很多这样的字符串格式化的stringlets,那么使用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() 
5

要插入一个很长的字符串它是好的,使用的名称为不同的参数,而不是希望他们在正确的位置。这也使得更换多个重复更容易。

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

Format examples,在所有其他Format - 相关答案也显示两者。

11

我不能完全肯定,我明白你的目标,但你可以使用一个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,与%格式化运算符或字符串的方法。

你当然可以定义一个函数来获取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 
+2

+1向我展示了如何在字符串格式化运算符(%)中使用* args。 – 2014-05-07 14:55:32

0

根据(此性能比较),列表解析是您最快的选择。这里是在Python 3.6引入了面向对象的实现,使用文本字符串插值(也被称为F-字符串):


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