Skip to content
Advertisement

Python: How to pass variables into decorators AND decorators pass decorator variables back into function as well?

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
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement