Чтение из файла вызывает ошибку IndexError в python - PullRequest
0 голосов
/ 17 июня 2020

Я делаю приложение, которое будет возвращать одну случайную строку из файла .txt. Я создал класс для реализации этого поведения. Идея заключалась в том, чтобы использовать один метод для открытия файла (который останется открытым) и другой метод, который закроет его после выхода из приложения. У меня нет большого опыта работы с файлами, поэтому мне кажется странным следующее поведение:

В __init__ Я позвонил self.open_file(), чтобы просто открыть его. И он отлично работает, чтобы получить self.len. Теперь я подумал, что мне не нужно снова вызывать self.open_file(), но когда я вызываю file.get_term() (возвращает случайную строку), он вызывает IndexError (как будто файл пуст), но если я снова вызываю метод file.open_file() , все работает, как ожидалось.

В дополнение к этому close_file() метод вызывает AttributeError - object has no attribute 'close', поэтому я предположил, что файл каким-то образом закрывается автоматически, даже если я не использовал with open.

import random
import os


class Pictionary_file:

    def __init__(self, file):
        self.file = file
        self.open_file()
        self.len = self.get_number_of_lines()

    def open_file(self):
        self.opened = open(self.file, "r", encoding="utf8")

    def get_number_of_lines(self):
        i = -1
        for i, line in enumerate(self.opened):
            pass
        return i + 1

    def get_term_index(self):
        term_line = random.randint(0, self.len-1)
        return term_line

    def get_term(self):
        term_line = self.get_term_index()
        term = self.opened.read().splitlines()[term_line]

    def close_file(self):
        self.opened.close()


if __name__ == "__main__":
    print(os.getcwd())
    file = Pictionary_file("pictionary.txt")
    file.open_file()                            #WITHOUT THIS -> IndexError
    file.get_term()
    file.close()                            #AttributeError

Где моя ошибка и как ее исправить?

1 Ответ

1 голос
/ 17 июня 2020

Здесь, в __init__:

self.open_file()
self.len = self.get_number_of_lines()

self.get_number_of_lines() фактически потребляет весь файл, потому что он выполняет итерацию по нему:

def get_number_of_lines(self):
    i = -1
    for i, line in enumerate(self.opened):
        # real all lines of the file
        pass
    # at this point, `self.opened` is empty
    return i + 1

Итак, когда get_term вызывает self.opened.read() , он получает пустую строку, поэтому self.opened.read().splitlines() - это пустой список.

file.close() - AttributeError, потому что класс Pictionary_file не имеет метода close. Однако у него есть close_file.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...