2014-07-16 36 views
1

我已經寫了一些Python代碼中使用fileinputinplace操作文件,其中沿該線看起來:使用Python的的FileInput與虛擬文件/ RAM文件

import fileinput 

def do_stuff_with_file(filename, parameters): 
    for line in fileinput.input(filename, inplace=1): 
     new_line = do_a_lot_of_stuff_with(line, parameters) 
     print_something(line, parameters) 
     print new_line, 
     print_some_more(line, parameters) 

do_stuff_with_file(["a.dat","b.dat"], parameters[1]) 
do_stuff_with_file("c.dat", parameters[2]) 
do_stuff_with_file("a.dat", parameters[3]) 
for i in range(100): 
    do_stuff_with_file("d.dat", parameters[i]) 

雖然我叫do_stuff_with_file通常一次或兩次每個文件都有一個文件(這裏是d.dat),我經常這樣稱呼它,這會導致文件¹不必要的讀寫。

有沒有什麼好的方法來改變上面的代碼而不改變使用的功能,使這個特殊的文件只讀取一次?我在尋找與操作系統無關的方法,例如,我無法在RAM磁盤上創建文件的臨時副本,或者希望操作系統足夠智能,以避免在程序完成之前實際將文件寫入磁盤。

途徑這個問題,我能想到的,但需要的功能,我沒能找到:

  • 獲取fileinput對字符串而不是一個文件進行操作。
  • 「倒帶」fileinput莫名其妙。
  • 確保文件保持打開狀態(並使用臨時副本)。
  • 找到一些其他處理字符串或使用print類似的模塊,如fileinput那樣。
  • 以一些與操作系統無關的方式創建一個Python內部的虛擬文件。

注意fileinput通過重定向print向寫入文件的當前位置實現文件操作在自己特有的方式,尤其如此。因此,使用相同的(或非常相似的)操作來修改別的東西,例如一個字符串,沒有直接的方法。這是我的問題的主要原因。

+0

嘗試將此函數更改爲一個類並創建它的子類,它應稍微更改此函數。這樣'a.dat'abd'b.dat'將在父類方法和'c。dat'將會在子類方法中被刪除。 –

+0

@ f.rodrigues:這會如何避免多次打開並寫入'd.dat'? – Wrzlprmft

回答

-1

如果您不希望中斷代碼的基本結構,可以應用如下所示的小型重構。你的代碼我

import fileinput 

def do_stuff_with_file(lines, filename, parameters): 
    for line in lines: 
     if fileinput.filename() == filename: 
      new_line = do_a_lot_of_stuff_with(line, parameters) 
      print_something(line, parameters) 
      print new_line, 
      print_some_more(line, parameters) 
     else: 
      print line 

filenames = ["a.dat", "b.dat", "c.dat"] 
lines = fileinput.input(filenames, inplace=1) 

do_stuff_with_file(lines, "a.dat", parameters) 
do_stuff_with_file(lines, "b.dat", parameters) 
do_stuff_with_file(lines, "a.dat", parameters) 
do_stuff_with_file(lines, "c.dat", parameters) 
do_stuff_with_file(lines, "c.dat", parameters) 
+0

經過一些簡單的測試(因此不在我的代碼中)後,我非常確定這段代碼將會清空'b.dat'和'c.dat',因爲在''線迭代過程中沒有'print'語句第一次調用'do_stuff_with_file'。而且,在第一個之後所有的'do_stuff_with_file'調用都不會做任何事情,因爲你只能迭代一次'fileinput.input'對象。 – Wrzlprmft

-1

展望會移動的讀/寫出來的do_stuff_with_file功能,而是隻將數據傳遞給函數。這需要你在其他地方打開文件。如果你按照我的說法創建這個類,你可以創建三個方法,一個用於打開和關閉文件,一個用於清理內存,另一個用於修改 - 它在第一個內部被調用。

class FileManipulation(): 
    def __init__(self, filename): 
     self.filename = filename 
     self.data = open(self.filename,'r').read() 


    def fileManage(self, parameters): 
     f = open(self.filename,'w') 
     output = self.do_stuff_with_file(self.data, parameters) 
     f.write(output) 
     f.close() 

    def fileManageOpen(self): 
     self.data = open(self.filename, 'r').read() 

    def fileManageClose(self): 
     self.data = None 

    def do_stuff_with_file(self,data, parameters): 
     output = None 
     for line in data: 
      output = do_a_lot_of_stuff_with(line, parameters) 
     return output 

def do_something_using(n_parameter): 
    ## do something with this number 
    pass 

a = FileManipulation('a.dat') 
b = FileManipulation('b.dat') 
c = FileManipulation('c.dat') 

a.fileManageOpen() 
a.fileManage(do_something_using(a.data[1])) 
a.fileManageClose() 

b.fileManageOpen() 
b.fileManage(do_something_using(b.data[2])) 
b.fileManageClose() 

new_parameters = [] 

c.fileManageOpen()  
for i in xrange(100): 
    new_parameters.append(do_something_using(c.data[i])) 

c.fileManage(new_parameters) 
c.fileManageClose() 

這樣,只有當你調用fileManageOpen()你實際上是讀取文件,do_something()將只與已經存儲在實例中的數據處理。

對不起,如果這不是太有用,但你的問題對我來說有點抽象,我不知道爲什麼你需要打開和關閉文件不止一次,如果你改變它100次,它會保留一樣。

+0

當然,我只能處理該文件一次,但是我必須爲其編寫全新的代碼,並且不能重複使用'do_stuff_with_file'。 – Wrzlprmft

+0

也許你可以使用getattr來獲取實例的數據(假設你將文件名作爲字符串)並將其傳遞給do_stuff_with_file。 –