Pythonic, an elegant way to dynamically determine a list of statically defined functions?

I recently started learning Python. Let me explain what I'm trying to accomplish. I have this .py script, which basically has several functions (hard-coded in a script) that all need to be added to one list so that I can get the function I need, just using the index operator as it should:

needed_function = function_list [required_function_index]

My first attempt to implement this led to the following code structure:

(imports) function_list = [] (other global variables) def function_0 = (...) function_list.append(function_0) def function_1 = (...) function_list.append(function_1) def function_2 = (...) function_list.append(function_2) (rest of code) 

But I do not like this solution, because it is not very elegant. My goal is to simply add a function definition to the script (without calling add), and the script will automatically add it to the list of functions.

I was thinking of defining all the functions within the framework of another function, but I do not think that I get anything with them. I thought it might be possible to "tag" each function as a decorator, but I realized that decorators (if I understand them correctly) are called every time the function is called, and not just once.

After a while, I came up with this solution:

 (imports) (global variables) def function_0 = (...) def function_1 = (...) def function_2 = (...) function_list= [globals()[x] for x in globals() if re.match('^function_[0-9]+$', x)] (rest of code) 

I like this a bit more as a solution, but my only embarrassment is that I would prefer for the sake of cleanliness to fully define the function_list at the top of the script. However, I cannot do this, since the call to globals () at the top of the script will not contain functions, since they are not defined yet.

Maybe I just need to settle for a less elegant solution, or maybe I'm not writing my script in an idiomatic way. In any case, any suggestions and suggestions are welcome.

+4
source share
3 answers

You are mistaken regarding decorators. They are called once when the function is defined, and the function returned is the value assigned to the name of the function, and this is the function that is called every time. You can do what you want in the decorator without requiring overhead runtime.

 my_functions = [] def put_in_list(fn): my_functions.append(fn) return fn @put_in_list def function1(): pass @put_in_list def function2(): pass 

PS: In any case, you probably don't need to worry about exceeding the lead time.

PPS: you are also trying to optimize odd things, you might be better off just maintaining a list in your file. How often do you add features and how little do you think? The list is not difficult to update in the source file.

+8
source

An example of using a decorator that does not add any overhead for calling a function:

 my_list = [] def add_to_my_list(func): print 'decorator called' my_list.append(func) return func @add_to_my_list def foo(): print 'foo called' @add_to_my_list def bar(): print 'foo called' print '-- done defining functions --' my_list[0]() my_list[1]() 
+1
source

One way to solve this problem would be to put all these functions in one container, and then extract the functions from the container to create a list.

The most Pythonic container will be class . I am not saying that they act as a member of a class; just define them in the class.

 class MyFunctions(object): def func0(): pass def func1(): pass lst_funcs = [x for x in MyFunctions.__dict__ if not x.startswith('_')] 

But I like another decorator approach; which is probably the most pythonic solution.

0
source

All Articles