При использовании readlines и функции .split () в Python, было бы проще пройти через цикл for? - PullRequest
0 голосов
/ 09 сентября 2018

Я создал цикл while для итерации, прочитал файл data.txt, вычислил периметр / площадь / вершины, и корень распечатает ответы.

Я застрял здесь:

from Polygon import Polygon
from Rectangle import Rectangle

in_file = open('data.txt', 'r')

line = in_file.readlines()

while line:
    type_, num_of_sides = line.split( ) ###ERROR 'list' object has no attribute 'split'

    sides = [map(float, in_file.readline().split()) for _ in range(int(num_of_sides))]
    print(line)

    if type_ == 'P':
        poly_object = Polygon(sides)

    elif type_ == 'R':
        poly_object = Rectangle(sides)

    print('The vertices are {}'.format(poly_object.vertices))
    print('The perimeter is {}'.format(poly_object.perimeter()))
    print('The area is {}'.format(poly_object.area()))
    print()

    line = in_file.readline()

in_file.close()

Должен ли я создать цикл for, который проходит через цикл, так как readlines - это список строк, и я хочу, чтобы разделение читало каждую строку? Или это просто способ форматирования, поэтому я получаю сообщение об ошибке?

1 Ответ

0 голосов
/ 09 сентября 2018

Непосредственной проблемой является использование readlines, а не readline в line = in_file.readlines().Это заполнит line списком всех строк из файла, а не одной строкой.Это приведет к двум проблемам с вашей программой, когда неправильный тип данных будет распространяться через цикл:

  1. Вызов while line, в этом случае после чтения непустого файла вызовет циклбыть выполненным, потому что непустой список оценивается как true.
  2. Вы вызываете split на line.На первой итерации цикла line содержит список строк (где каждая строка была строкой в ​​файле).Списки, у которых нет split метода - есть только отдельные строки.Этот вызов завершается ошибкой.
  3. Если вызов split не завершился неудачно и цикл был разрешен один раз, последующий вызов line = in_file.readline() не вернул бы следующую строку в файле, так как всестроки были прочитаны предыдущим вызовом readlines, и курсор не был сброшен за прошедший период из EOF.Цикл прекратится.

Если у вас не было последнего вызова на шаге 3, вместо этого цикл будет выполняться вечно без завершения, так как значение line никогда не будет обновлено до-impty list.


Минимальным изменением является настройка начального вызова, который присваивает значение переменной line для readline() вместо readlines(), чтобы обеспечить чтение только одной строки изфайл.В этом случае логика в коде должна работать.


Возможно, вам легче реализовать следующую логику реализации и рассуждать о том, как:

  • собрать механизм для чтения из in_fileвместе в единый блок перед циклом, используя менеджер контекста для автоматического закрытия файла при выходе из блока
  • , создавая список строк, чего достаточно для простого цикла forперебрать
# This context manager will automatically ensure `in_file` is closed
# on leaving the `with` block.
with open('data.txt', 'r') as in_file:
    lines = in_file.readlines()

for line in lines:
    # Do something with each line; in particular, you can call
    # split() on line without issue here.
    #
    # You do not require any further calls to in_file.readline()
    # in this block.
...