I am testing a bunch of functions and want to get the name of the function I tested to be printed to the console.
if __name__ == '__main__':
passedMsg = "%s passed"
failedMsg = "%s failed"
list_of_functions = [testaddDict(), testaddDictN(), testcharCount(), testcharCount2(), testlookupVal(),
testlookupVal2(), testfunRun(), testnumPaths(), testnumbersToSum(), teststreamSquares(),
teststreamSquares()]
for i in range(0, len(list_of_functions)):
if list_of_functions[i]:
print (passedMsg % str(list_of_functions[i]))
else:
print (failedMsg % str(list_of_functions[i]))
When I do the above, instead of a function name, I was given:
True passed
for every iteration. Where did I do wrong?
1 Answer 1
First, have your list hold the function objects (this means that you shouldn't call them, because if you do, you end up holding the return values instead).
list_of_functions = [testaddDict, testaddDictN, ...]
This works because functions are first class objects in python (meaning you can assign them to other variables, and so on). Next, modify your loop as such, to iterate directly over list_of_functions:
for f in list_of_functions:
if f():
print(passedMsg % f.__name__)
else:
print(failedMsg % f.__name__)
The most important change is that you call the function in the if statement, and determine, by its return value, whether it has passed or failed. Print f.__name__ accordingly, where the __name__ attribute holds the "name" of the function.
Why I recommend iterating over the function list directly (and not over the range), is mainly for efficiency and simplicity sake.
Here's a demo with two functions:
def f1():
return True
def f2():
return False
for f in [f1, f2]:
if f():
print(passedMsg % f.__name__)
else:
print(failedMsg % f.__name__)
f1 passed
f2 failed
2 Comments
if f() line, since that change is pretty subtle and there are other changes, like skipping the range that might distract from the important one.
()invokes the function. Try[... testaddDict...]()and then print outlist_of_functions[i].__name__