advanced programming techniques one theoretical problem with this approach is that it is potentially insecure the name variable could begin with sysand be followed by some destructive code and here is the third approachagain just showing the replacement for the first approach' try except blocktrymodule __import__(namemodules append(moduleexcept (importerrorsyntaxerroras errprint(errthis is the easiest way to dynamically import modules and is slightly safer than using exec()although like any dynamic importit is by no means secure because we don' know what is being executed when the module is imported none of the techniques shown here handles packages or modules in different pathsbut it is not difficult to extend the code to accommodate these--although it is worth reading the online documentationespecially for __import__()if more sophistication is required having imported the module we need to be able to access the functionality it provides this can be achieved using python' built-in introspection functionsgetattr(and hasattr(here' how we have used them to implement the get_function(functiondef get_function(modulefunction_name)function get_function cache get((modulefunction_name)noneif function is nonetryfunction getattr(modulefunction_nameif not hasattr(function"__call__")raise attributeerror(get_function cache[modulefunction_namefunction except attributeerrorfunction none return function get_function cache {ignoring the cache-related code for momentwhat the function does is call getattr(on the module object with the name of the function we want if there is no such attribute an attributeerror exception is raisedbut if there is such an attribute we use hasattr(to check that the attribute itself has the __call__ attribute--something that all callables (functions and methodshave (further on we will see nicer way of checking whether an attribute is collections callable