2014-12-19 2 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)? –

+0

@ Mr.WorshipMe - Хороший вопрос. Было бы целесообразно также вызвать close в '__del__'. Достаточно ли этого, зависит от других целей дизайна. Например, экземпляры классов могут долгое время находиться после предложения 'with', но может быть желательно как можно скорее закрыть файл. Существует риск того, что вызов '__del__' отложен на некоторых реализациях python, оставляя открытую или круглую опорную задержку файла закрытой до сбора мусора. – tdelaney

+0

Проблема заключается в том, что __del__ вызывается ПОСЛЕ того, как объект был разыменован (когда ссылки на объект класса равны нулю), то есть имя, содержащее открытый файл, больше не существует, когда вы вызываете __del__. –

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 
Смежные вопросы