I have a library function to which a user can pass their own function that will be executed at various points during the library function’s execution. Sometimes, these user functions may want to access (not modify) variables that only exist inside the library function. This is the current implementation:
def lib_func(user_func=None): lib_var1 = 'somevalue' lib_var2 = 'othervalue' ... if user_func: user_func(lib_var1,lib_var2) ... if user_func: user_func(lib_var1,lib_var2)
The problem is that sometimes the user’s function may not need lib_var1
or lib_var2
, and currently they still need to write them as arguments:
def my_func(a,b): <some-code-not-involving-a-or-b> lib_func(my_func)
Is there a better way to deal with this situation where the user doesn’t need to have unnecessary arguments in their function?
Advertisement
Answer
One approach is to require different functions for different contexts. If some argument is not passed to the function in some case, then the function does not have the same role in that context.
Ask yourself if the function has the same role in both cases, if it does not maybe require multiple functions.
def lib_func(fun_context1=None, fun_context2=None): # case with all arguments if fun_context1: fun_context1(lib_var1, lib_var2) # specialized case with only one argument if fun_context2: fun_context2(lib_var1) # User's function def my_func1(foo, bar): ... def my_func2(foo): ... lib_func(my_func1, my_func2)
The above solution works to a point… there may well be an unpractical amount of special cases. If so, you could require the user to provide a function which takes a **kwargs
argument. This will give the user’s function the flexibility to check which parameters were passed to it and what to do in each case.
def lib_func(user_func=None): if user_func: user_func(lib_var1=lib_var1, lib_var2=lib_var2) # case with only one parameters if user_func: user_func(lib_var1=lib_var1) # User's function def my_func(**params): lib_var1 = params.get("lib_var1") lib_var2 = params.get("lib_var2") lib_func(my_func)
Another benefit of this approach in maintainability. If your library ever provide additional keyword arguments to the user-defined function, this will not break the user’s code.