Пустой файл не читается как пустой в 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
,
Я попробовал следующий пустой список и тесты файлов:
Обе версии не смогли инициировать инициализацию файла. См. Правки ниже для получения дополнительной информации о том, как заставить эти решения работать. Примечание: я использую 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 = []
пустой.