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.
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.
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]
I have a python file named as test1.py.
This file contains few classes and a few functions.
I intend to package this and distribute so that others can use it via the pip install command.
From other posts, I understood how we build a package.
Q: When the package is imported in the end user's code, using the import <mypackage> command,
1. can the functions be called directly by simply writing the function name?
2. methods which are part of the class, are ideally called by objectname.methodname, how will they be called now?
It depends on how you import the package. If you import the package as
import test1
you will have to call all the classes and functions with test1.function(). The class methods like test1.objectname.methodname()
If you use
from test1 import *
you can just use the function names, but your namespace is being polluted with all the function names.
You can also import only specific functions or classes using
from test1 import function1, function2, class1, class2
To call them with just their respective name.
And lastly you can use import test1 as t1 to make it a bit shorter, calling functions can then be done using t1.function1()
functions will be appended to the package name. For example:
import numpy
# Calling the square root function from numpy
val = 4
newVal = numpy.sqrt(val)
# You can also do this, but it is not recommended as it pollutes your name space
from numpy import sqrt
# Now I can call sqrt directly
val = 4
newVal = sqrt(val)
Class methods work similarly.
I am working on a pretty huge Python package. Inside several modules, different programmers import other modules to do calculations. For the sake of this discussion, let's stick to numpy.
Common practice, when importing modules is defining an alias for easier programming, so let's say in a module foo.py there is a line doing
import numpy as np
So there will be a foo.np namespace. I also found out, that by deleting the reference to np inside foo.py by doing
del np
at the end of the module seems to clear the namespace as well.
As a maintainer of a huge package, I like this way of keeping the namespace clean but I wonder if this is good programming practice or if there are problems arising especially if my package has a module bar.py in the same level as foo.py which also uses the same external numpy module? If yes, is there a simple and better way to keep the namespaces of foo and bar clean or is this housekeeping of namespaces itself a bad idea?
Here is a simple example:
foo.py:
import numpy as np
def foo(x):
"""Return 2D square array of zeros."""
return np.zeros((x, x))
del np
bar.py:
import numpy as np
def bar():
"""Return 3x3 square array."""
return np.arange(9).reshape(3, 3)
main.py:
from bar import bar
from foo import foo
print bar()
print foo(3)
And here are the outputs:
[[0 1 2]
[3 4 5]
[6 7 8]]
Traceback (most recent call last):
File "/Users/jonrsharpe/Documents/main.py", line 6, in <module>
print foo(3)
File "/Users/jonrsharpe/Documents/foo.py", line 5, in foo
return np.zeros((x, x))
NameError: global name 'np' is not defined
So clearly this has not affected bar.py (which you should expect - del removes that reference, but doesn't affect the underlying object) but has broken the functionality imported from foo.py, as np is no longer accessible to the objects defined in that file.
is this housekeeping of namespaces itself a bad idea?
I'm not sure what you see as the benefits of it. Removing names from the namespace of a module you've finished using is not going to save very much (if any) space, and the underlying imported module (numpy, in this case) will still be in sys.modules.
Given this situation:
Foo.py:
import another_module
def foo():
#some code
It is called by different modules, some of them already import another_module,some other don't.(let's call one of them 'main.py')
Which is the default behaviour? Is the module re-loaded?If yes,(that's just a curiosity) let's suppose that another_module has changed between the import in the main and the import in foo.py. Python does have in memory two different version of another_module,one accessible for foo.py and one for main.py?
Is there a way to not import another_module if it has already been done in the main?
How does it works if in the main i have from another_module import f1, and in foo.py from another_module import f1,f2.Is f2 just "added" or module reloaded?
No, modules are not reloaded. You can use the reload() function to reload a module. After importing a module it is being added to the sys.modules dictionary. As the documentation states, you can also force a module to be reloaded by altering contents of this variable:
This can be manipulated to force reloading of modules and other tricks. Note that removing a module from this dictionary is not the same as calling reload() on the corresponding module object.
The from statement isn't any difference with regard to this behaviour. It just controls which parts of the loaded module are being added to the current scope:
Import statements are executed in two steps: (1) find a module, and initialize it if necessary; (2) define a name or names in the local namespace (of the scope where the import statement occurs). The statement comes in two forms differing on whether it uses the from keyword. The first form (without from) repeats these steps for each identifier in the list. The form with from performs step (1) once, and then performs step (2) repeatedly.
You can easily verify this yourself:
y.py:
print "Y"
def f1():
pass
def f2():
pass
x.py:
print "X"
from y import f1, f2
test.py:
from y import f1
import x
print "reload"
reload(x)
python test.py
Y
X
reload
X