Getting corresponding module from function
Question:
I want to modify a module xyz and its functions like that:
def modify(fun):
modulename = fun.__module__ # this is string. ok, but not enough
import xyz
modify(xzy.test)
My problem is how to access the namespace of xzy
inside modify
. Sometimes
globals()[fun.__module__]
works. But then I get problems if the definition modify
is in a different file than the rest of
the code.
Answers:
You could try
modulename = fun.__module__
module = __import__(modulename)
You want to get the module object from its name? Look it up in the sys.modules
dictionary that contains all currently loaded modules:
import sys
def modify(func):
module = sys.modules[func.__module__]
You do not want to do this.
-
It does not work. Imagine you defined a function in module abc
and then imported it in xyz
. test.__module__
would be 'abc'
when you called modify(xyz.test)
. You would then know to change abc.test
and you would not end up modifying xyz.test
at all!
-
Monkey patching should be avoided. Fooling with the global state of your program is ill-advised. Instead of doing this, why cannot you just make the new, modified thing and use it?
Use the inspect module:
import inspect
def modify(fun):
module = inspect.getmodule(fun)
This is the same as polling the module from sys.modules
using fun.__module__
. Although getmodule
tries harder even if fun
does not have a __module__
attribute.
I want to modify a module xyz and its functions like that:
def modify(fun):
modulename = fun.__module__ # this is string. ok, but not enough
import xyz
modify(xzy.test)
My problem is how to access the namespace of xzy
inside modify
. Sometimes
globals()[fun.__module__]
works. But then I get problems if the definition modify
is in a different file than the rest of
the code.
You could try
modulename = fun.__module__
module = __import__(modulename)
You want to get the module object from its name? Look it up in the sys.modules
dictionary that contains all currently loaded modules:
import sys
def modify(func):
module = sys.modules[func.__module__]
You do not want to do this.
-
It does not work. Imagine you defined a function in module
abc
and then imported it inxyz
.test.__module__
would be'abc'
when you calledmodify(xyz.test)
. You would then know to changeabc.test
and you would not end up modifyingxyz.test
at all! -
Monkey patching should be avoided. Fooling with the global state of your program is ill-advised. Instead of doing this, why cannot you just make the new, modified thing and use it?
Use the inspect module:
import inspect
def modify(fun):
module = inspect.getmodule(fun)
This is the same as polling the module from sys.modules
using fun.__module__
. Although getmodule
tries harder even if fun
does not have a __module__
attribute.