2014-12-19 71 views
1

嘿,我有一個下面的問題,我需要打開一個文件__init__(),並與check函數我需要檢查此文件的行中的字符串/數字是否相同。如果他們不是,應該返回True,如果他們應該返回False,並且如果沒有更多行None。我不知道文件中會有多少行。我的代碼是有用的,測試人員給我90%,但它說我沒有關閉文件,我明白爲什麼它說,但不知道在哪裏結束。但是,如果我打開它with它應該工作,但我不知道如何得到它的工作方式。在__init中打開文件__()python

我的代碼:

class Program: 
    def __init__(self, file_name): 
     self.t = open(file_name, 'r') 

    def check(self): 
     row = self.t.readline() 

     array = [] 

     for i in row.split(): 
      if i not in array: 
       array.append(i) 

     if row.split() == []: 
      return None 
     elif array == row.split(): 
      return True 
     else: 
      return False 

""" 
#testing 

if __name__ == '__main__': 
    u = Program('file.txt') 
    z = True 
    while z is not None: 
     z = u.check() 
     print(z) 

""" 

示例文件:

15 9 22 
2014 2015 2014 2015 
p py pyt pyth pytho python 
ab ab ab ab ab 
+0

是的,你永遠不會'關閉'文件。文件是否足夠小以至於您可以將它讀入內存?或者你能構建自己的代碼作爲上下文管理器嗎? – jonrsharpe

+0

@jonrsharpe不知道如果我完全理解問題的第二部分,但文件不應該有點大,您可以看到示例文件,因此它應該具有相似的大小,或者只是更多的幾行。 – Matis

+0

如果你的類有兩個方法,其中之一是'__init __()',它不應該是一個類,而是一個函數。 –

回答

5

既然你在一個方法打開該文件,並使用它的另一個,你可以」 t使用班級內部的with聲明。您可以添加一個方法來關閉文件,並讓關閉成爲調用者的問題。主叫方的解決方案是使用contextlib.closing。把它放在一起......

class Program: 
    def __init__(self, file_name): 
     self.t = open(file_name, 'r') 

    def check(self): 
     ... 

    def close(self): 
     if self.t: 
      self.t.close() 
      self.t = None 


import contextlib 
with contextlib.closing(Program('myfile.txt')) as program: 
    program.check() 
+0

如果我們只是從__del __(self)調用close,會發生什麼? –

+0

@ Mr.WorshipMe - 好問題。在'__del__'中調用close也是有意義的。這是否足夠取決於其他設計目標。例如,類實例可能會在'with'子句後生存很長時間,但可能需要儘快關閉文件。在某些python實現中,'__del__'調用被延遲,導致文件打開或循環引用延遲關閉,直到垃圾收集。 – tdelaney

+0

問題是,在調用__del__時,__del__被稱爲AFTER對象已被取消引用(對類對象的引用爲零時),意味着保存打開文件的名稱不再存在。 –

0

我想你應該實例化類和「檢查」的方法應一次檢查一行。

這工作,但如果你的老師沒有告訴你關於yield發言中,他會知道你在騙:

class Program(object): 
    def __init__(self, fname): 
     self.line_checker = self.make_checker(fname) 

    def make_checker(self, fname): 
     with open(fname) as i: 
      for line in i: 
       yield len(set(line.split())) < 2 

    def check(self): 
     try: 
      return self.line_checker.next() 
     except StopIteration: 
      return None