I'm trying to create my first Python Project, which is a software to make some adjustments in a database file (gdb file).
The idea to structure the code is the following:
In my main function i create a MAP dict, which will be populate from function to function, like so:
def phase2(MAP):
# do something
return MAP
def phase1(MAP):
# do something...
return MAP
def main():
MAP = {}
phase1_result = phase1(MAP)
phase2_result = phase2(phase1_result)
And so on... like an fluent interface. My question is: is there a better approach to call a function passing the result from another? The idea is avoid changing global variables, avoiding side effects.
Thanks!
I have a config.py file which as a bunch of bool parameters like
show_timer = True
display_graph = True
My main code runs in a while loop, and the loop seems very cluttered with code that is not executed if the above parameters are False. What is the best approach for readability for this kind of configuration file driven codes? I am currently using a format like:
init_someting() if display_graph else None
while True:
do_something() if show_timer else None
.
.
.
As Martijn said in his comment, don't use a conditional expression; use a normal if statement. It seems like you've got all the actions in functions already, so I don't think there's much else to do.
if display_graph:
init_something()
while True:
if show_timer:
do_something()
if other_option:
do_other_thing()
For Educational Purposes Only (but there are places where this pattern is useful)
Depending on the details of what you're doing, you could also use the config options to build a list of functions to be called, then loop repeatedly over that. Something like this:
if display_graph:
init_something()
functions_to_call = []
if show_timer:
functions_to_call.append(do_something)
if other_option:
functions_to_call.append(do_other_thing)
while True:
for function in functions_to_call:
function()
Or:
if display_graph:
init_something()
all_functions = [
(show_timer, do_something),
(other_option, do_other_thing),
]
functions_to_call = [function for (flag, function) in all_functions if flag]
while True:
for function in functions_to_call:
function()
/For Educational Purposes Only
If keeping additional objects is not a constraint, you can have a dict with config to function mapping.
func_dict = {'show_timer': timer_func,
'display_graph': display_graph_func}
Now iterate over func_dict to check config values. Something like:-
for config_param, func_obj in func_dict.items():
if config[config_param]:
func_obj()
or in shorthand:-
[func_obj() for config_param, func_obj in func_dict.items() if config[config_param]
But again passing parameters to functions will be an issue. Check if you can work out on it.
I have router that is deciding which function to call based upon user input (uses ConfigParser) and then tries to decide which function to call.
def SomethingElse():
print 'hello'
def UploadDirectory():
print 'hi'
def router(config):
if config.has_option('job', 'Some_Task'):
taskName = config.get('job', 'Some_Task')
# taskName is now 'UploadDirectory'
###execute the UploadDirectory function
###execute something else if something else, etc
So what is the way to write this in python? If I prebuilt a map of functions to strings, can i execute them that way?
How would you write this?
Yep, building a map of strings to function names is perfectly valid:
task_map = {
'upload': UploadDirectory,
'something': SomethingElse,
}
And execute as:
task_map[task_name]()
Aside: try to follow PEP-8, the python style guide; it helps make your code more readable to all other Python programmers. Specifically in this case, prefer underscore_separated function names instead of LeadingCaps.
Another hacky way to do it is to use globals(), if you're not running just by importing the router function:
globals()[taskName]()
In python 3.4, I want to be able to do a very simple dispatch table for testing purposes. The idea is to have a dictionary with the key being a string of the name of the function to be tested and the data item being the name of the test function.
For example:
myTestList = (
"myDrawFromTo",
"myDrawLineDir"
)
myTestDict = {
"myDrawFromTo": test_myDrawFromTo,
"myDrawLineDir": test_myDrawLineDir
}
for myTest in myTestList:
result = myTestDict[myTest]()
The idea is that I have a list of function names someplace. In this example, I manually create a dictionary that maps those names to the names of test functions. The test function names are a simple extension of the function name. I'd like to compute the entire dictionary from the list of function names (here it is myTestList).
Alternately, if I can do the same thing without the dictionary, that'd be fine, too. I tried just building a new string from the entries in myTestList and then using local() to set up the call, but didn't have any luck. The dictionary idea came from the Python 3.x documentation.
There are two parts to the problem.
The easy part is just prefixing 'text_' onto each string:
tests = {test: 'test_'+test for test in myTestDict}
The harder part is actually looking up the functions by name. That kind of thing is usually a bad idea, but you've hit on one of the cases (generating tests) where it often makes sense. You can do this by looking them up in your module's global dictionary, like this:
tests = {test: globals()['test_'+test] for test in myTestList}
There are variations on the same idea if the tests live somewhere other than the module's global scope. For example, it might be a good idea to make them all methods of a class, in which case you'd do:
tester = TestClass()
tests = {test: getattr(tester, 'test_'+test) for test in myTestList}
(Although more likely that code would be inside TestClass, so it would be using self rather than tester.)
If you don't actually need the dict, of course, you can change the comprehension to an explicit for statement:
for test in myTestList:
globals()['test_'+test]()
One more thing: Before reinventing the wheel, have you looked at the testing frameworks built into the stdlib, or available on PyPI?
Abarnert's answer seems to be useful but to answer your original question of how to call all test functions for a list of function names:
def test_f():
print("testing f...")
def test_g():
print("testing g...")
myTestList = ['f', 'g']
for funcname in myTestList:
eval('test_' + funcname + '()')
There is an eval() function in Python I stumbled upon while playing around. I cannot think of a case when this function is needed, except maybe as syntactic sugar. Can anyone give an example?
eval and exec are handy quick-and-dirty way to get some source code dynamically, maybe munge it a bit, and then execute it -- but they're hardly ever the best way, especially in production code as opposed to "quick-and-dirty" prototypes &c.
For example, if I had to deal with such dynamic Python sources, I'd reach for the ast module -- ast.literal_eval is MUCH safer than eval (you can call it directly on a string form of the expression, if it's a one-off and relies on simple constants only, or do node = ast.parse(source) first, then keep the node around, perhaps munge it with suitable visitors e.g. for variable lookup, then literal_eval the node) -- or, once having put the node in proper shape and vetted it for security issues, I could compile it (yielding a code object) and build a new function object out of that. Far less simple (except that ast.literal_eval is just as simple as eval for the simplest cases!) but safer and preferable in production-quality code.
For many tasks I've seen people (ab-)use exec and eval for, Python's powerful built-ins, such as getattr and setattr, indexing into globals(), &c, provide preferable and in fact often simpler solutions. For specific uses such as parsing JSON, library modules such as json are better (e.g. see SilentGhost's comment on tinnitus' answer to this very question). Etc, etc...
The Wikipedia article on eval is pretty informative, and details various uses.
Some of the uses it suggests are:
Evaluating mathematical expressions
Compiler bootstrapping
Scripting (dynamic languages in general are very suitable to this)
Language tutors
You may want to use it to allow users to enter their own "scriptlets": small expressions (or even small functions), that can be used to customize the behavior of a complex system.
In that context, and if you do not have to care too much for the security implications (e.g. you have an educated userbase), then eval() may be a good choice.
In the past I have used eval() to add a debugging interface to my application. I created a telnet service which dropped you into the environment of the running application. Inputs were run through eval() so you can interactively run Python commands in the application.
In a program I once wrote, you had an input file where you could specify geometric parameters both as values and as python expressions of the previous values, eg:
a=10.0
b=5.0
c=math.log10(a/b)
A python parser read this input file and obtained the final data evaluating the values and the expressions using eval().
I don't claim it to be good programming, but I did not have to drive a nuclear reactor.
I use it as a quick JSON parser ...
r='''
{
"glossary": {
"title": "example glossary"
}
}
'''
print eval(r)['glossary']['title']
You can use eval in a decorator:
#this replaces the original printNumber with a lambda-function,
#which takes no arguments and which calls the old function with
#the number 10
#eval("lambda fun: lambda: fun(10)")
def printNumber(i: int) -> None:
print("The number is %i", i)
#call
printNumber()
while you cannot use complex expressions like
#lambda fun: lambda: fun(10)
def ...
nor
#(lambda fun: lambda: fun(10))
def ...
You cannot use a lambda-expression there, because the decorator should either be an identifier:
#myModule.functionWithOneArg
or a function call:
#functionReturningFunctionWithOneArg(any, "args")
You see that the call of the function eval with a string has valid syntax here, but the lambda-expression not. (-> https://docs.python.org/3/reference/compound_stmts.html#function-definitions)
eval() is not normally very useful. One of the few things I have used it for (well, it was exec() actually, but it's pretty similar) was allowing the user to script an application that I wrote in Python. If it were written in something like C++, I would have to embed a Python interpreter in the application.
Eval is a way to interact with the Python interpreter from within a program. You can pass literals to eval and it evaluates them as python expressions.
For example -
print eval("__import__('os').getcwd()")
would return the current working directory.
cheers
eval() is for single sentence, while exec() is for multiple ones.
usually we use them to add or visit some scripts just like bash shell.
because of they can run some byte scripts in the memory, if you have some important data or script you can decode and unzip your 'secret' then do everything you wanna.
I just came across a good use of eval. I was writing a test suite for some code, and created a Test class, where every method was a test to be run. I wanted a way so that I could run all the test methods without having to call each method individually. So, I wrote something rather dirty.
class Test:
def __init__(self, *args):
#bs
def test1(self):
#bs
def test2(self):
#bs
if __name__ == "__main__":
import argparse
#argparse bs
test = Test(*bs_args)
for func in (i for i in dir(test) if i[0] != '_' and i not in test.__dict__):
print(eval('test.{func}()'.format(func = func)))
Dynamic evaluation of arbitrary test cases is pretty cool. I just have to write the method, and after saving I can include the method in my test suite. As for the code, I basically just inspect the methods defined in the test object, and make sure they aren't default python "magic" methods or attributes to the Test object. After that I can assume they are methods and can be evaluated.
I used it to input variable values to the main program:
test.py var1=2 var2=True
...
var1=0
var2=False
for arg in sys.argv[1:]:
exec(arg)
A crude way to allow keyword args in the main program. If there's a better way let me know!
I had a case where I used eval in combination with an informix database. For some reason the query returned a string formed like this
query_result = "['1', '2', '3']"
I just used eval on the query result so python interpreted it as a list of strings.
[int(i) for i in eval(query_result)]
> [1,2,3]
I could not change the db so this was a quick (and dirty) way to get the integers.
I use exec to create a system of plugins in Python.
try:
exec ("from " + plugin_name + " import Plugin")
myplugin = Plugin(module_options, config=config)
except ImportError, message:
fatal ("No such module " + plugin_name + \
" (or no Plugin constructor) in my Python path: " + str(message))
except Exception:
fatal ("Module " + plugin_name + " cannot be loaded: " + \
str(sys.exc_type) + ": " + str(sys.exc_value) + \
".\n May be a missing or erroneous option?")
With a plugin like:
class Plugin:
def __init__ (self):
pass
def query(self, arg):
...
You will be able to call it like:
result = myplugin.query("something")
I do not think you can have plugins in Python without exec/eval.