My program reads a file (batch_files
) that contains a list of file names containing tranches of data. If batch_files
is empty, the code will create a new text file. If batch_files
contains file names, the program will append data to the existing file(s).
Here is my original code/pseudo code, which worked in 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.
In Python 3.6.6, I receive the following error:
PermissionError: [Errno 13] Permission denied:'[error message includes the working directory path without a filename]'
Even though batch_files
is empty, i.e. batch_names = ['']
, len(batch_names)
equals 1 (per debugging trace). The code then skips the file initialization subroutine because if series_count == 0
is false. Then the code tries to load a non-existent data file but produces an error because there is no text in file_name
.
I tried the following empty list and file tests:
Both versions failed to trigger file initialization. See edits below for more information on getting these solutions to work.
Side Note: I am using Notepad++ to ensure batch_files
is empty. The file size is 0k. OS is Windows 10.
Why does my code think batch_files
isn't empty? How do you suggest I fix the problem?
Edit: Per @saarrrr, the list contains an empty text string, so I used the following code to solve the issue.
Preferred Method:
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:
Alternatively:
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:
Also, if os.stat(path + batch_files).st_size == 0:
will work. This option failed for me initially because I had pointed batch_files
to the wrong file.
I don't understand why a list with an empty text string isn't empty. Nor do I understand why my original conditional worked in 3.5 but not 3.6. Explanations of the problem's source or more pythonic solutions are welcome.
Edit 2: Link to Standard Library discussing lists. Nested empty lists are possible. Empty text strings aren't mentioned; however, I'm assuming the same logic applies to other data types, i.e. an empty data type is considered a list element.