2011-11-03 62 views
58

我不是一個專業人士,我一直在撓頭理解StringIO的用途。我一直在找互聯網尋找一些例子。但是,幾乎所有的例子都非常抽象。他們只是展示「如何」使用它。但是他們沒有一個顯示「爲什麼」和「在哪種情況下」應該/將會使用它? 在此先感謝Python中的StringIO在現實中用於什麼?

P.不要與這個問題在計算器上混淆:StringIO Usage它比較字符串和StringIo。

回答

75

當你有一些只接收文件的API時使用它,但你需要使用一個字符串。例如,在Python 2壓縮使用gzip模塊的字符串:

import gzip 
import StringIO 

stringio = StringIO.StringIO() 
gzip_file = gzip.GzipFile(fileobj=stringio, mode='w') 
gzip_file.write('Hello World') 
gzip_file.close() 

stringio.getvalue() 
+0

換句話說:'duck typing':D – Abdelouahab

+1

自Python 3.2以來,gzip模塊具有直接壓縮數據的功能。 (但是目前需要StringIO的任何着名的開源庫可能會在一段時間後增長這樣的功能,所以不是尋找一個新的例子,我會在這裏留下gzip。) –

27

StringIO爲您提供對文件的字符串訪問,因此您可以使用現有的模塊來處理文件,並且幾乎不做任何改變,並且可以使用字符串。

例如,假設您有一個將事物寫入文件的記錄器,而您希望通過網絡發送日誌輸出。您可以讀取該文件並將其內容寫入網絡,也可以將日誌寫入到一個StringIO對象,並將其發送到其網絡目標,而無需觸及文件系統。 StringIO可以很容易地完成第一種方式,然後切換到第二種方式。

12

在你想要的行爲像一個文件一個文件對象的情況,但被寫入到內存中的字符串緩衝區:StringIO的是工具。如果要構建大型字符串(如純文本文檔)並進行大量字符串連接,則可能會發現使用StringIO而不是一堆mystr += 'more stuff\n'操作類型更容易。的事情,我個人已經使用了

+1

我還發現'StringIO'是如果你在循環中處理多個兆字節的字符數據時比使用'mystr + =「更多的東西\ n」'更加快速,特別是如果你可以使用'cStringIO.StringIO'而不是'io.StringIO' '。 – SeldomNeedy

8

夫婦:

  1. 全文件緩存。我有一個讀取PDF文件的腳本,並對他們的各種事情進行驗證。我正在使用的PDF庫在文檔構造函數中使用了一個打開的文件。我原本打開了我對閱讀感興趣的PDF,但是當我將它改爲一次將整個文件讀入內存時,將一個StringIO對象傳遞給PDF庫,我的腳本運行時間減半。

  2. 延期打印。相同的腳本在每次讀取PDF之前都會打印一個標題。但是,我可以在命令行上指定是忽略配置文件中的某些測試,還是隻包含某些測試。如果我忽略全部測試給定的PDF我不想打印頭,但我不知道我運行測試(測試可以動態定義)之前運行了多少測試。因此,我通過將sys.stdout更改爲指向它來將頭部捕獲到StringIO對象中,並且每次運行測試時都會檢查該對象是否有任何內容。如果是這樣,我打印它然後重置它爲空。瞧,只有有測試的PDF文件纔會打印標題。

7

我只是用StringIO的實踐了兩件事情:

  • 進行單元測試的腳本,做了很多print ING的,通過重定向sys.stdoutStringIO實例簡單的分析;
  • 使用ElementTree創建保證格式良好的XML文檔(自定義API請求),然後使用write通過HTTP連接發送。

不是你需要StringIO經常,但有時它是非常有用的。

0

Django具有用於調用管理命令的功能call_command。該函數將輸出打印到標準輸出並且不返回任何值。如果您想知道命令是否成功運行,您必須查看輸出並做出決定。

使用StringIO,您可以捕獲輸出並檢查是否需要輸出。

with io.StringIO() as output: 
    call_command('custom_command', stdout=output) 
    if 'Success' not in output.getvalue(): 
     print('Custom command failed...')