I use numpy and scipy for data analysis. I want to write a code inside a function that I define so that when the function is called it check if, for example, numpy is imported and if it is not imported, then it should import it.
How can I check if any module such as numpy imported?
You can use sys.modules in the sys module for this:
>>> import sys
>>> import numpy
>>> 'numpy' in sys.modules
True
So your function could be:
def is_imported(module):
return module in sys.modules
From the comments, you also wanted to return True if you'd used
from skimage.morphology import watershed
You can check if a function is in the current namespace by using dir()
>>> 'watershed' in dir()
False
>>> from skimage.morphology import watershed
>>> 'watershed' in dir()
True
To import a module using a string, you can use importlib.import_module():
>>> import importlib
>>> importlib.import_module('numpy')
The import statement is idempotent - it already checks whether the module has been loaded. Using import module in your function already does what you want:
def my_func():
import numpy # load numpy if not available
# use numpy
This works for all kinds of imports, including submodules, relative imports and aliasing of members.
def my_other_func():
# load skimage, skimage.morphology, and
# skimage.morphology.watershed if they are unimported modules
from skimage.morphology import watershed
During import, the module name is looked up in sys.modules and if present, the associated value is the module satisfying the import, and the process completes. [...]
[The Python Language Reference: the import system]
Related
I have a module where a number of different functions use random numbers or random choices.
I am trying to use mock and patch to inject pre-chosen values in place of these random selections but can't understand an error I am receiving.
In the function I am testing, I use
np.random.randint
when I use the code
from unittest import mock
import random
mocked_random_int = lambda : 7
with mock.patch('np.random.randint', mocked_random_int):
I get an error message no module named np. However, numpy is imported as np and other functions are calling it just fine.
Even more perplexing if I edit the code above to remove the 'np' at the front it does what I want:
with mock.patch('random.randint', mocked_random_int):
But I want to understand why the code works without the np. Thank you!
There is a difference between a module or package name and the variable it is assigned to in any given namespace. A simple import
import numpy
tells python to check its imported module list, import numpy as necessary, and assign the module to the variable "numpy"
import numpy as np
is almost the same, except that you assign to a variable "np". Its still the same numpy package, its just that you've aliased it differently.
mock.patch will import and patch the module regardless of whether you've already imported it, but you need to give the module name, not your current module's alias to the module.
So I found a problem while "creating" modules. Let's say I create a nice module called foo in which I define a function named function that depends on numpy:
foo.py:
"""
This is foo a nice module
"""
import numpy as np
def function(parameter):
return(np.zeros(parameter))
Then in another script I want to call my module:
import foo
So my problem is that numpy module is loaded inside foo so I can call it from foo (for example I can foo.np.zeros())
Is there any way that I'm not aware of in which the module will still work without having all numpy loaded inside it (naturally numpy should be loaded globally so foo works but i don't want it to be accessible from foo.np)
So far I've tried:
if __name__ == '__main__':
import numpy as np
But this breaks the module foo even if numpy is loaded.
I would simply like to understand why a call for keras like from tf import keras will not work in the following code, while I am already importing tensorflow as tf in the first line?
import tensorflow as tf
from tf import keras
Error:
ModuleNotFoundError: No module named 'tf'
However, the following would work -
import tensorflow as tf
from tensorflow import keras
Thanks!
This is because the import statement is responsible for finding your modules in the first place. It doesn't look in your current name space for variable bindings, which is where the alias tf is stored. This can also be thought of as your alias never renaming the target module:
>>> import sys as s
>>> s.__name__
'sys'
If keras is already an available name (as if any code had done import tensorflow.keras), you can still find that name within the imported module, so you could do something like keras = tf.keras then.
You can think of import foo as bar as a combination of import foo ; bar = foo ; del foo, except it never actually used the name foo in your local namespace.
It is possible, but quite awkward, to find the submodule using the given alias as well:
import importlib
import sys
import http as h
# Module name lookup method 1:
name = [k for (k,v) in sys.modules.items() if v is h][0]
# Module name lookup method 2:
name = h.__name__
c = importlib.import_module('.client', name)
Method 1 searches all currently imported modules to find the one that is h, which produces its imported (not just local) name, and uses a relative import from that. Quite likely method 2 also suffices, but it may not in case e.g. that entry has been deleted.
This question already has an answer here:
Is there a way to bypass the namespace/module name in Python?
(1 answer)
Closed last month.
I am using Canopy with the Jupyter notebook. I was wondering if there was a way to use function from a module without having to call the module. For example if I have
import numpy as np
print np.sin(2)
I would want to be able to just type
print sin(2)
The first thing that comes to mind is to add the numpy functions into whatever function library that Python is using. But I was wondering if this is feasible and, if so, how I could go about doing it. Note that I want to import all functions, not just a select few.
You can import specific objects from a module. Try:
from numpy import sin
print sin(2)
To import all objects from a module into the global namespace you can use import *.
from numpy import *
print sin(2)
But this is not recommended because you can easily end up with name clashes, e.g. if two modules define a function named sin which version of sin should be called?
>>> import math
>>> import numpy
>>> math.sin
<built-in function sin>
>>> numpy.sin
<ufunc 'sin'>
>>> from math import *
>>> sin
<built-in function sin>
>>> from numpy import *
>>> sin
<ufunc 'sin'>
You can see here that the second import from numpy replaced sin in the global namespace.
For this reason it is best to import the specific objects that you need if there are only a few, otherwise just import the module and use the module name as a prefix (as per your first example). In my example if you wanted to use both math.sin and nump.sin you would either need to import the modules only and prefix using the module name, or import the functions and rename them like this:
from numpy import sin as np_sin
from math import sin
from numpy import sin
print sin(2)
https://docs.python.org/2/tutorial/modules.html read this in details
I have recently installed scikit-image version 0.11.3. I am using python 2.7.10. When I import the entire module I cannot access the io module.
import skimage
img = skimage.io.imread(path_)
Gives error:
AttributeError: 'module' object has no attribute 'io'
However the following does not error.
from skimage import io
img = io.imread(path_)
Question: Why?
Quick answer: IO is a submodule. Submodules need to be imported from the parent module explicitly.
Long answer: From section 5.4.2 of the python docs:
When a submodule is loaded using any mechanism (e.g. importlib APIs, the import or import-from statements, or built-in import()) a binding is placed in the parent module’s namespace to the submodule object. For example, if package spam has a submodule foo, after importing spam.foo, spam will have an attribute foo which is bound to the submodule. Let’s say you have the following directory structure:
spam/
__init__.py
foo.py
bar.py
and spam/init.py has the following lines in it:
from .foo import Foo
from .bar import Bar
then executing the following puts a name binding to foo and bar in the spam module:
>>>
>>> import spam
>>> spam.foo
<module 'spam.foo' from '/tmp/imports/spam/foo.py'>
>>> spam.bar
<module 'spam.bar' from '/tmp/imports/spam/bar.py'>
Given Python’s familiar name binding rules this might seem surprising, but it’s actually a fundamental feature of the import system. The invariant holding is that if you have sys.modules['spam'] and sys.modules['spam.foo'] (as you would after the above import), the latter must appear as the foo attribute of the former.
It's simply the way Python handles modules.
One reason is that it would make importing one module very slow if cpython needed to scan for submodules, import all of them and then import all of their submodules.
The other reason is "better be explicit than implicit". Why should Python import everything possible when you only need a small fraction of a package with a complex module hierarchy.
Instead of from skimage import io you can also write
import skimage.io
then skimage.io.imread will be found.