How to get the active module as object - python

When you import another python-file the variable with the same name is assigned with a module-object:
>>> import somemodule
>>> somemodule
<module 'somemodule' from '/home/code/test/somemodule.py'>
But how do you get the active module as an object in somemodule.py itsself, which should be the same object as the variable somemodule in <stdin>?

You can get the name of the current module from __name__. That name will look something like package.module (assuming your file is in package/module.py).
Use that string to access the module inside sys.modules but beware: you don't want to do this while the module load is in progress! While your module's outermost level code is being run, the module definitions are still in a state of flux -- you can't necessarily count on always being able to access everything.
For specific example, the module statements are executed top to bottom. So if you access the module in the middle, any variables and functions defined above the access will be in the module, but things defined below the access will not have been executed, and so won't be in the module yet. Whoops!

Related

'import' and 'from import' behaves differently

As per my understanding, the difference between 'import' and 'from import' in Python is: 'import' imports the whole library, 'from import' imports a specific member or members of the library, and there should not be any behavioral difference.
As per this, I was expecting both the test1.py and test2.py to show the same result i.e. "Lucky". But it is different for test2.py. Can anyone explain why?
mymodule.py
message = "Happy"
def set_message(msg):
global message
message = msg
test1.py
import mymodule
mymodule.set_message("Lucky")
print(mymodule.message) #output is Lucky
test2.py
from mymodule import *
set_message("Lucky")
print(message) #output is Happy
'import' imports the whole library, 'from import' imports a specific member or members of the library, and there should not be any behavioral difference.
Both versions - assuming the module has not already been imported - cause the top-level code to execute and a module object to be created.
import ... means that the module object is assigned to the corresponding name in the local namespace. (The reason the . syntax works is that the global variables from when the module's code was running, become attributes of that modle object.)
from ... import * means that Python iterates over the attributes of the module object, and assigns each name into the current namespace, similarly.
For subsequent code, the module object itself is the global namespace in which its functions run.
Your test2.py calls a method from mymodule, causing it to do a global lookup of message. That lookup finds the message attribute of the module object, and replaces it. The message global variable in your own code is unchanged, because neither was that name reassigned, nor was the value modified (it was replaced). It is the same as if you do:
# Functions are the easiest way to get an object with mutable attributes
def namespace(): pass
namespace.a = 3
a = namespace.a # "import" the name
namespace.a = 4 # replace the value; `a` does not change

Get package of Python object

Given an object or type I can get the object's module using the inspect package
Example
Here, given a function I get the module that contains that function:
>>> inspect.getmodule(np.memmap)
<module 'numpy.core.memmap' from ...>
However what I really want is to get the top-level module that corresponds to the package, in this case numpy rather than numpy.core.memmap.
>>> function_that_I_want(np.memmap)
<module 'numpy' from ...>
Given an object or a module, how do I get the top-level module?
If you have imported the submodule, then the top-level module must also be loaded in sys.modules already (because that's how the import system works). So, something dumb and simple like this should be reliable:
import sys, inspect
def function_that_I_want(obj):
mod = inspect.getmodule(obj)
base, _sep, _stem = mod.__name__.partition('.')
return sys.modules[base]
The module's __package__ attribute may be interesting for you also (or future readers). For submodules, this is a string set to the parent package's name (which is not necessarily the top-level module name). See PEP366 for more details.

How does importing a function from a module work in Python?

I have a module some_module.py which contains the following code:
def testf():
print(os.listdir())
Now, in a file named test.py, I have this code:
import os
from some_module import testf
testf()
But executing test.py gives me NameError: name 'os' is not defined. I've already imported os in test.py, and testf is in the namespace of test.py. So why does this error occur?
import is not the same as including the content of the file as if you had typed it directly in place of the import statement. You might think it works this way if you're coming from a C background, where the #include preprocessor directive does this, but Python is different.
The import statement in Python reads the content of the file being imported and evaluates it in its own separate context - so, in your example, the code in some_module.py has no access to or knowledge of anything that exists in test.py or any other file. It starts with a "blank slate", so to speak. If some_module.py's code wants to access the os module, you have to import it at the top of some_module.py.
When a module is imported in Python, it becomes an object. That is, when you write
import some_module
one of the first things Python does is to create a new object of type module to represent the module being imported. As the interpreter goes through the code in some_module.py, it assigns any variables, functions, classes, etc. that are defined in that file to be attributes of this new module object. So in your example, the module object will have one attribute, testf. When the code in the function testf wants to access the variable os, it looks in the function itself (local scope) and sees that os is not defined there, so it then looks at the attributes of the module object which testf belongs to (this is the "global" scope, although it's not truly global). In your example, it will not see os there, so you get an error. If you add
import os
to some_module.py, then that will create an attribute of the module under the name os, and your code will find what it needs to.
You may also be interested in some other answers I've written that may help you understand Python's import statement:
Why import when you need to use the full name?
Does Python import statement also import dependencies automatically?
The name testf is in the namespace of test. The contents of the testf function are still in some_module, and don't have access to anything in test.
If you have code that needs a module, you need to import that module in the same file where that code is. Importing a module only imports it into the one file where you import it. (Multiple imports of the same module, in different files, won't incur a meaningful performance penalty; the actual loading of the module only happens once, and later imports of the same module just get a reference to the already-imported module.)
Importing a module adds its name as an attribute of the current scope. Since different modules have independent scopes, any code in some_module cannot use names in __main__ (the executed script) without having imported it first.

How to get reference to module by string name and call its method by string name?

The modules are already imported in the current module ( no need of dynamic import ), and have an ALIAS name.
The requirement is to get reference to the module by its alias name, and call its function
current module :
import libraries.mymaths.products as myproductlib
def call_func(module_name,method_name):
# module_name = 'myproductlib' , method_name='mult'
# how to call myproductlib.mult here ?
getattr(MODULE_REF, method_name) would help me to get reference to method, but how to get reference to module by its alias name ?
To get the module, you can use globals. To get the function, use getattr:
getattr(globals()[module_name], function_name)
Importing a module just binds the module object to a name in whatever namespace you import it in. In the usual case where you import at the top level of the module, this means it creates a global variable.
BrenBarn's globals() solution works with the module name, ALIASESED or not, only if the import is located in this module (the one currently running).
If you still want to get hold of the module by its unaliased name (e.g. it was imported earlier, from some other module), get it from sys.modules with a FQN module name like "apackage.somemodule":
>>> import sys
>>> import libraries.mymaths.products as myproductlib
>>> globals()["myproductlib"] == sys.modules["libraries.mymaths.products"]
True

Having to evaluate a string to access a class from a module

I've loaded one of my modules <module my_modules.mymodule from .../my_modules/mymodule.pyc> with __import__.
Now I'm having the module saved in a variable, but I'd like to create an instance of the class mymodule. Thing is - I've gotten the module name passed as string into my script.
So I've got a variable containing the module, and I've got the module name but as string.
variable_containing_module.string_variable_with_correct_classname() doesn't work. Because it says there is no such thing in the module as "string_variable_with_correct_classname" - because it doesn't evaluate the string name. How can I do so?
Your problem is that __import__ is designed for use by the import internals, not really for direct usage. One symptom of this is that when importing a module from inside a package, the top-level package is returned rather than the module itself.
There are two ways to deal with this. The preferred way is to use importlib.import_module() instead of using __import__ directly.
If you're on an older version of Python that doesn't provide importlib, then you can create your own helper function:
import sys
def import_module(module_name):
__import__(module_name)
return sys.modules[module_name]
Also see http://bugs.python.org/issue9254

Categories