I want to read file name(A/B/C/D) and call the convenable function for each file in Files folder and then process the next file (pass automatically to the next file and function).
I have multiple files stored in Files folder:
Here is the directory structure:
App/
├─ main.py
└─ Files/
└─B.txt
└─A.xlsx
└─folderC
| └─filec1.txt
| └─filec2.txt
└─D.xlsx
└─folderF
└─fileF1.txt
└─fileF2.txt
I have multiple functions stored in main.py:
def A_fct(fileA):
pass
def B_fct(fileB):
pass
def C_fct(fileC1,fileC2):
pass
def D_fct(fileD):
pass
def F_fct(files):
df = pd.concat([pd.read_csv(f,sep='\t',engine="python") for f in
glob.glob(files "/*.txt")],ignore_index=True)
NB: Somes functions have 2 arguments.
Example:
read file Name B.txt => call B_fct
read file Name A.xlsx => call A_fct
etc ...
I tried this solution:
path = ''
name_to_func = {
"A.xlsx": A_fct,
"B.txt": B_fct,
...
}
for files in os.listdir(path):
name_to_func[file_name](files)
This solution is worked very well for me when functions have only one argument but sometimes I have exceptions and I have a fonction with 2 arguments for Exp C_fct(fileC1,fileC2)
How can I fix this please!
CodePudding user response:
You can check if a path is a directory with os.path.isdir
and change the call arguments.
base_path = 'Files/'
for name in os.listdir(base_path):
path = os.path.join(base_path, name)
if os.path.isdir(path):
files = [os.path.join(path, f) for f in os.listdir(path)]
if name_to_func[path].__code__.co_argcount == len(files):
name_to_func[path](*files)
else:
name_to_func[path](files)
else:
name_to_func[path](path)
In this case the list of files will be used as arguments to the function.
If you are not sure how many parameters would the function get you can rewrite the definition as well:
def C_fct(*files):
files # is the list of arguments
However, you can avoid *
notation simply providing a list as an argument.