Home > Net >  A more eloquent way to perform same file check before multiple functions
A more eloquent way to perform same file check before multiple functions

Time:09-01

I think this is simple but I am just not seeing it. I want to check that a file exists; if it does I read it into a list, but if not I create it. Example:

filename = "a_file_name"
filepath = os.path.join(os.getcwd(), filename)

if not os.path.exists(filepath): 
    foo() #do some stuff then create file
    with open(filename, 'w') as f:
        for item in a_list:
            f.write(f"{item}\n")
else:
    #if the file already exists read it into a list
    a_list = [line.rstrip() for line in open(filepath)]

This works fine the problem is I have to do this more than once (but different filename/path) so same code surrounding foo(), same code for bar(), etc. I thought a decorator would work here but the problem is I have to return the list if the file does exist and decorators only return the function.. So seeking another option to make this more eloquent than repeating myself multiple times.

CodePudding user response:

You can create a list of tuples of filename-function pairs and then iterate through the pairs instead.

To propagate the returning values of earlier functions to the latter ones, you can pass a dict to each function call and save the returning value to the dict with the function object as the key for latter functions to retrieve it:

def foo(result):
    return 1

def bar(result):
    return 2   result[foo] # returns 3 in this example

file_checks = [
    ('a_file_name', foo),
    ('b_file_name', bar)
]
result = {}

for filename, func in file_checks:
    filepath = os.path.join(os.getcwd(), filename)
    
    if not os.path.exists(filepath): 
        result[func] = func(result)
        with open(filepath, 'w') as f:
            for item in a_list:
                f.write(f"{item}\n")
    else:
        a_list = [line.rstrip() for line in open(filepath)]
  • Related