Пустой файл не читается как пустой в Python 3

Моя программа читает файл (batch_files), который содержит список имен файлов, содержащих транши данных. Если batch_files пуст, код создаст новый текстовый файл. Если batch_files содержит имена файлов, программа добавит данные в существующие файлы.

Вот мой оригинальный код / ​​псевдокод, который работал в Python 3.5:

    with open(path + batch_files, 'r+', encoding='utf-8') as file_list:
        batch_names = [line.rstrip('\n') for line in file_list]
        series_count = len(batch_names)
        # Initialize an empty batch if none exists.
        if series_count == 0:
            series_count += 1
            Pseudo-code: create file and append file name to `batch_files`
        # Load existing batches.
        for file_name in batch_names:
            with open(path + file_name, 'r', encoding='utf-8') as tranche:
                Pseudo-code: append data to existing file.

В Python 3.6.6 я получаю следующую ошибку:

PermissionError: [Errno 13] В доступе отказано: "[сообщение об ошибке содержит путь к рабочему каталогу без имени файла]"

Даже если batch_files пусто, т.е. batch_names = [''], len(batch_names) равно 1 (за трассировку отладки). Затем код пропускает подпрограмму инициализации файла, потому что if series_count == 0 ложно Затем код пытается загрузить несуществующий файл данных, но выдает ошибку, потому что нет текста в file_name,

Я попробовал следующий пустой список и тесты файлов:

  1. if not batch_names: по этой теме.
  2. if os.stat(path + batch_files).st_size == 0: по этой теме.

Обе версии не смогли инициировать инициализацию файла. См. Правки ниже для получения дополнительной информации о том, как заставить эти решения работать. Примечание: я использую Notepad++ для обеспечения batch_files пустой. Размер файла составляет 0 КБ. ОС Windows 10.

Почему мой код думает batch_files не пусто? Как вы предлагаете мне исправить проблему?

Edit: Per @saarrrr, список содержит пустую текстовую строку, поэтому я использовал следующий код для решения проблемы.

Предпочитаемый метод:

    batch_list = [line.rstrip('\n') for line in file_list]
    # Remove empty text strings.
    batch_names = list(filter(None, batch_list))
    # Initialize an empty batch if none exists.
    if not batch_names:

В качестве альтернативы:

    batch_list = [line.rstrip('\n') for line in file_list]
    batch_names = list(filter(None, batch_list))
    series_count = len(batch_names)
    # Initialize an empty batch if none exists.
    if series_count == 0:

Также, if os.stat(path + batch_files).st_size == 0: буду работать. Этот вариант потерпел неудачу для меня изначально, потому что я указал batch_files в неправильный файл.

Я не понимаю, почему список с пустой текстовой строкой не пуст. Также я не понимаю, почему мои оригинальные условные работали в 3.5, но не 3.6. Разъяснения источника проблемы или более питонических решений приветствуются.

Редактировать 2: Ссылка на списки обсуждения в стандартной библиотеке. Возможны вложенные пустые списки. Пустые текстовые строки не упоминаются; однако, я предполагаю, что та же логика применяется к другим типам данных, т.е. пустой тип данных считается элементом списка.

1 ответ

Сообщение об ошибке пишет PermissionError, что означает, что у вас нет разрешения на чтение / запись файла (r+ режим означает чтение и запись), независимо от содержимого файла.

Также, как указал @saarrrr, batch_names = [''] означает, что в нем есть пустая строка, которая не является пустой. batch_names = [] пустой.

Другие вопросы по тегам