2011-03-15 95 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()