I need to have a generic script which takes some_module.function as argument and executes it. I wrote a solution for this (has to be Python-2.4 compatible...):
def get_function(f_name):
"""Return function from library..."""
lib, f = f_name.rsplit('.', 1)
module = getattr(__import__(lib), lib.rsplit('.', 1)[-1])
return getattr(module, f)
f = get_function('my_libs.testlib.test_function')
# finally, this executes the function
f()
My question is:
Why do I have to do the getattr()
after __import__()
?
Turns out module = __import__('lib')
will have the namespace above the one of lib .
So when I wanted to call a function from lib , say lib.f_x , I would have to do it like:
module = __import__('lib')
module.lib.f_x()
instead of what I would expect:
module = __import__('lib')
module.f_x()
Or use the contruct with getattr()
as above. Why is that?
As given in the documentation -
When the name variable is of the form
package.module
, normally, the top-level package (the name up till the first dot) is returned, not the module named by name.
Why? Because lets say you asked it to import blah.something
, what should be returned would be blah
with something
being an attribute inside blah
(hence the requirement to use getattr
) .
A simple solution to this should be -
def get_function(f_name):
"""Return function from library..."""
lib = f_name.rsplit('.', 1)[0]
modl = __import__(lib)
comps = f_name.split('.')[1:]
for comp in comps:
modl = getattr(modl,comp)
return modl
The above also works if you are simply importing module , or a function from a module or a package, etc.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.