I'm trying to determine the actual current module of a function (as seen if imported from elsewhere), even if the current module is the "top level scripting environment" __main__
.
It may sound like a weird thing to do, but the background is that I need to serialize a function and unserialize it (including arguments) on a different machine, for which I need to make sure the correct module AND NOT __main__
is imported before deserializing (otherwise I get an error saying AttributeError: 'module' object has no attribute my_fun
).
So far, I've tried inspection:
import inspect
print inspect.getmodule(my_fun)
which gives me
<module '__main__' from 'example.py'>
of course. I also tried finding something useful using globals()
, no luck.
What I really want is <module 'example' from 'example.py'>
. I suppose a hacky way would be to parse it from the file name using something like
m_name = __main__.__file__.split("/")[-1].replace(".pyc","")
and then find the module by name sys.modules[m_name]
.
Is there a cleaner/better way to do this?
EDIT:
After learning about ipython's "FakeModule" and a bit more googling, I came accross this post, which describes exactly the problem that I'm facing, including my current solution to it (which is explicitly importing the current module import current_module
and serializing current_module.my_fun
instead of my_fun). I'm trying to avoid this, as it might not be intuitive for the users of my package.
In Python, the special name __main__ is used for two important constructs: the name of the top-level environment of the program, which can be checked using the __name__ == '__main__' expression; and. the __main__.py file in Python packages.
A module can find out its own module name by looking at the predefined global variable __name__.
We can also use the inspect module in python to locate a module. We will use inspect. getfile() method of inspect module to get the path. This method will take the module's name as an argument and will return its path.
The current module, the module being executed (called also the main module) has a special name: '__main__' . With this name it can be referenced from the Python code. We have two files in the current working directory: empty.py and test_empty.py . The second module is the main module, which is executed.
I actually ran across this same problem.
What I used was:
return os.path.splitext(os.path.basename(__main__.__file__))[0]
Which is effectively the same as your "hack." Honestly, I think its the best solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With