Reputation: 184
I'm creating a small python app that formats a file's name to a set of rules. I'm having problems finding a way of applying a list of general formatting functions to the same string. I want to apply one function, then another, then another.
I've managed to find a way that works, but I feel that it's very clumsy.
Here I have a list of lists that includes one function and a dictionary of the kwargs. (All of these functions have a "text" parameter that is not included in the dictionary).
functions = [
[SRF.change, {'old': '.', 'new': ' '}],
[SRF.surround, {'value': SU.get_year}],
[SRF.remove, {'chars': '[],'}],
[SRF.capitalize_words, {}],
[SRF.remove_including, {'value': 'mp4'}]]
I then pass it into the custom_rename
function. It loops over the list of functions and applies it to the "text" variable. As you can see, the variable changes every time func(text, **kwargs)
is called.
def custom_rename(text, functions_list):
# Apply a list of functions to a string
for func_list in functions_list:
func = func_list[0] # Function
kwargs = func_list[1] # Dictionary
try:
text = func(text, **kwargs)
except AttributeError:
pass
return text
Is there a more elegant way of doing this? I, for example, do not like that I have to know that the function is in position [0] and the dictionary is in [1].
Upvotes: 0
Views: 58
Reputation: 43246
Instead of storing [function, arguments]
lists, you can use functools.partial
to create callables with the arguments already baked in:
from functools import partial
functions = [
partial(SRF.change, old='.', new=' '),
partial(SRF.surround, value=SU.get_year),
partial(SRF.remove, chars='[],'),
SRF.capitalize_words,
partial(SRF.remove_including, value='mp4')
]
Now your custom_rename
function can be simplified to this:
def custom_rename(text, functions_list):
# Apply a list of functions to a string
for func in functions_list:
try:
text = func(text)
except AttributeError:
pass
return text
Upvotes: 2