I am always looping through the files of a directory to perform various kinds of data manipulations. Thus, I always use the following code
for subdir, dirs, files in os.walk(dir_): for file_name in files: # manipulations here
Instead of keep writing these lines of code for every function, I was wondering if I can make it better by using decorators. Like the following:
# decorator def wrapper_layer1(directory): def wrapper_layer2(func): def wrapper_layer3(*args, **kwargs): for subdir, dirs, files in os.walk(dir_): for file_name in files: func(subdir, dirs, files, file_name) return wrapper_layer3 return wrapper_layer2 return wrapper_layer1 # function @wrapper_layer1(dir_=r"") def func(subdir, dirs, files, file_name): # manipulations here
I have found many resources out there which focus on how to pass parameters into the decorator. But in this case, it requires not only pass parameters into the decorator, also require decorator pass parameters to function.
Does anyone know how to achieve?
Advertisement
Answer
The function that takes arguments for the decorator function (wrapper_layer1
in your example) should return the decorator function, not itself. Similarly, the decorator function (wrapper_layer2
in your example) should return the wrapper function, not itself. And finally, the wrapper function (wrapper_layer3
in your example) should return something other than itself to the caller, if at all:
def for_each_file(dir_): def decorator(func): def wrapper(*args, **kwargs): for subdir, dirs, files in os.walk(dir_): for file_name in files: func(subdir, dirs, files, file_name) # return something meaningful, or don't return anything at all if # the caller does not expect a returning value return wrapper return decorator