問題
你要寫c擴充套件來讀取來自任何python類檔案物件中的資料(比如普通檔案、stringio物件等)。
解決方案
要讀取乙個類檔案物件的資料,你需要重複呼叫 read() 方法,然後正確的解碼獲得的資料。
下面是乙個c擴充套件函式例子,僅僅只是讀取乙個類檔案物件中的所有資料並將其輸出到標準輸出:
#define chunk_size 8192
/* consume a "file-like" object and write bytes to stdout */
static pyobject *py_consume_file程式設計客棧(pyobject *self, pyobject *args)
/* get the read method of the passed object */
if ((read_meth = pyobject_getattrstring(obj, "read")) == null)
/* build the argument list to read()www.cppcns.com */
read_args = py_buildvalue("(i)", chunk_size);
while (1)
/* check for eof */
if (pysequence_length(data) == 0)
/* encode unicode as bytes for c */
if ((enc_data=pyunicode_asencodedstring(data,"utf-8","strict"))==null)
/* extract underlying buffer data */
pybytes_asstringandsize(enc_data, &buf, &len);
/* write to stdout (replace with something more useful) */
write(1, buf, len);
/* cleanup */
py_decref(enc_data);
py_decref(data);
} result = py_buildvalue("");
final:
/* cleanup */
py_decref(read_meth);
py_decref(read_args);
return result;
}要測試這個**,先構造乙個類檔案物件比如乙個stringio例項,然後傳遞進來:
>>> import io
>>> f = io.stringio('hello\nworld\n')
>>> import sample
>>> sample.consume_file(f)
hello
world
>>>
討論和普通系統檔案不同的是,乙個類檔案物件並不需要使用低階檔案描述符來構建。 因此,你不能使用普通的c庫函式來訪問它。 你需要使用python的c api來像普通檔案類似的那樣操作類檔案物件。
在我們的解決方案中,read()方法從被傳遞的物件中提取出來。 乙個引數列表被構建然後不斷的被傳給pyobject_call()來呼叫這個方法。 要檢查檔案末尾(eof),使用了pysequence_len程式設計客棧gth()來檢視是否返回物件長度為0.
對於所有的i/o操作,你需要關注底層的編碼格式,還有位元組和unicode之前的區別。 本節演示了如何以文字模式讀取乙個檔案並將結果文字解碼為乙個位元組編碼,這樣在c中就可以使用它了。 如果你想以二進位制模式讀取檔案,只需要修改一點點即可,例如:
.../* call read() */
if ((data = pyobject_call(read_meth, read_args, null)) == null)
/* check for eof */
if (pysequence_length(data) == 0)
if (!pybytes_check(data))
/* extract underlying buffer data */
pybytes_asstringandsize(data, &buf, &len);
...本節最難的地方在於如何進行正確的記憶體管理。 當處理pyobject *變數的時候,需要注意管理引用計數以及在不需要的變數的時候清理它們的值。 對py_decref()的呼叫就是來做這個的。
本節**以一種通用方式編寫,因此他也能適用於其他的檔案操作,比如寫檔案。 例如,要寫資料,只需要獲取類檔案物件的write()方法,將資料轉換為合適的python物件 (位元組或unicode),然後呼叫該方法將輸入寫入到檔案。
最後,儘管類檔案物件通常還提供其他方法(比如readline(), read_info()), 我們最好只使用基本的read()和write()方法。 在寫c擴充套件的時候,能簡單就盡量簡單。
C語言中的物件導向 C語言中的類模擬
在物件導向的語言裡面,出現了類的概念。這是程式設計思想的一種進化。所謂類 是對特定資料的特定操作的集合體。所以說類包含了兩個範疇 資料和操作。而c語言中的struct僅僅是資料的集合。li 1978 163.com 1 例項 下面先從乙個小例子看起 ifndef c class define c c...
C語言中讀取相對路徑
在c語言實踐中,我們經常需要讀取與當前程式檔案在同一根目錄下的其它檔案或資料夾中的內容,這就需要用到相對路徑。c語言中的相對路徑 相對 麻煩,現舉例如下 假設程式源 檔案在c code practise 路徑下,我們需要讀取c code practise text 資料夾中的檔案0.txt,怎樣設定...
python簡單學習 類 類與物件 繼承 讀取檔案
python類的簡單學習 class person 建立乙個新類 pass 空白塊 p person 建立乙個物件 例項 print p 類中包含方法,與函式的區別是有乙個額外的self變數 class person1 def init self,name init 方法在類的乙個物件被建立時,馬上...