2014-12-19 39 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