Importing names from another python file - python

I've tried searching with Google and in stackoverflow, but I can't find the answer to this simple question, that has probably been asked many times before
In file f1.py, I have
import numpy as np
In file f2.py, I have
import f1
class One:
mat = np.array([[1]]))
When I run f2, I get the error message that 'np' is undefined. How should I express my obvious intentions?
To give background, I am writing my first python3 program that is not a toy program. f1 represents the substantial code. f2 is supposed to be a unittest program. However, some fundamental misunderstanding of python syntax is preventing me from making progress. I thought that the import of f1 would bring np into the namespace of f2, but it doesn't seem to.

I thought that the import of f1 would bring np into the namespace of f2, but it doesn't seem to.
Indeed. Each module has it's own namespace, and you have to explicitely import all modules you depend on. So if f2.py needs numpy, it has to explicitely import it:
import numpy as np
import f1
class One:
mat = np.array([[1]]))
NB : importing f1 doesn't directly injects any other name defined in f1 either, so if you have a function "foo" in f1, in f2 you'll need to either import f1 (as in the above example) and use the qualified name f1.foo() or explicitely import name "foo", ie from f1 import foo (but then you'll only get access to foo, not any of the other names defined in f1).

mat = np.array([[1]])
In this line the np is not in local namespace because you have not imported np in local namespace.
So if you have to use np you should use following line:-
mat = f1.np.array([[1]])
For more info go to this link import x and from x import

You should import np like this:
from f1 import np

Related

Why do I have to import this from numpy if I am just referencing it from the numpy module

Aloha!
I have two blocks of code, one that will work and one that will not. The only difference is a commented line of code for a numpy module I don't use. Why am I required to import that model when I never reference "npm"?
This command works:
import numpy as np
import numpy.matlib as npm
V = np.array([[1,2,3],[4,5,6],[7,8,9]])
P1 = np.matlib.identity(V.shape[1], dtype=int)
P1
This command doesn't work:
import numpy as np
#import numpy.matlib as npm
V = np.array([[1,2,3],[4,5,6],[7,8,9]])
P1 = np.matlib.identity(V.shape[1], dtype=int)
P1
The above gets this error:
AttributeError: 'module' object has no attribute 'matlib'
Thanks in advance!
Short Answer
This is because numpy.matlib is an optional sub-package of numpy that must be imported separately.
The reason for this feature may be:
In particular for numpy, the numpy.matlib sub-module redefines numpy's functions to return matrices instead of ndarrays, an optional feature that many may not want
More generally, to load the parent module without loading a potentially slow-to-load module which many users may not often need
Possibly, namespace separation
When you import just numpy without the sub-package matlib, then Python will be looking for .matlib as an attribute of the numpy package. This attribute has not been assigned to numpy without importing numpy.matlib (see discussion below)
Sub-Modules and Binding
If you're wondering why np.matlib.identity works without having to use the keyword npm, that's because when you import the sub-module matlib, the parent module numpy (named np in your case) will be given an attribute matlib which is bound to the sub-module. This only works if you first define numpy.
From the reference:
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.
Importing and __init__.py
The choice of what to import is determined in the modules' respective __init__.py files in the module directory. You can use the dir() function to see what names the respective modules define.
>> import numpy
>> 'matlib' in dir(numpy)
# False
>> import numpy.matlib
>> 'matlib' in dir(numpy)
# True
Alternatively, if you look directly at the __init__.py file for numpy you'll see there's no import for matlib.
Namespace across Sub-Modules
If you're wondering how the namespace is copied over smoothly;
The matlib source code runs this command to copy over the numpy namespace:
import numpy as np # (1)
...
# need * as we're copying the numpy namespace
from numpy import * # (2)
...
__all__ = np.__all__[:] # copy numpy namespace # (3)
Line (2), from numpy import * is particularly important. Because of this, you'll notice that if you just import numpy.matlib you can still use all of numpy modules without having to import numpy!
Without line (2), the namespace copy in line (3) would only be attached to the sub-module. Interestingly, you can still do a funny command like this because of line (3).
import numpy.matlib
numpy.matlib.np.matlib.np.array([1,1])
This is because the np.__all__ is attached to the np of numpy.matlib (which was imported via line (1)).
You never use npm but you do use np.matlib, so you could change your 2nd import line to just:
import numpy.matlib
Or you could keep your 2nd import line as is but instead use:
P1 = npm.identity(V.shape[1], dtype=int)
Is there are reason you don't use np.identity?
P1 = np.identity(V.shape[1], dtype=int)
This module contains all functions in the numpy namespace, with the following replacement functions that return matrices instead of ndarrays.
Unless you are wedded to 2d np.matrix subclass, you are better off sticking with the regular ndarray versions.
(Others have pointed out that the import why is based on the __init__ specs for numpy. numpy imports most, but not all of its submodules. The ones it does not automatically import are used less often. It's a polite way of saying, You don't really need this module)

Way to run all packages I want in python script

There are many times that I want to use same packages in my scripts, I mostly copy paste packages I want from my last script. I want to stop this work and run all of theme with one simple function, Today i try this:
def econometrics():
print("Econometrics is starting")
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
import statsmodels.api as sm
import matplotlib.pyplot as plt
print("Econometrics is started")
econometrics()
the function runs without error but when I call some method from packages, I get errors like this:
name 'plt' is not defined
What is wrong with that code? is there anyway to define function to do that?
What is wrong with that code?
Simple answer: Variable scope. plt (and the others) are only accessible from within the econometrics method.
Try making one file, named importer.py, for example
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
import statsmodels.api as sm
import matplotlib.pyplot as plt
Then in your other code (that is in the same directory),
from importer import *
Using an __init__.py is probably the recommended way to approach that, though, but it wasn't clear if you have a module/package layout, or not.
If you do, then use
Relative import (same directory): from . import *
Absolute import (use module name): from some_module import *
Your intent is wrong in python's grammar. Because within your code, the variables range are scoped within the function. So, when you do your imports, you're creating a bunch of variables within the econometrics function range, and thus your variables are only in reach within that function.
So, let's take a simpler example:
>>> def foobar():
... a = 1
... b = 2
...
>>> foobar()
>>> a
NameError: name 'a' is not defined
here a and b only exist within foobar's function scope, so it's out of scope at the main scope.
To do what you want, the way you want it, you should declare your variable as belonging to the global scope:
def econometrics():
global pd, np, smf, sm, plt
print("Econometrics is starting")
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
import statsmodels.api as sm
import matplotlib.pyplot as plt
print("Econometrics is started")
econometrics()
So to get back to the foobar example:
>>> def foobar():
... global a, b
... a = 1
... b = 2
...
>>> foobar()
>>> a
1
>>> b
2
Though, I do not really like that way of doing things, as it's doing things implicitely. Considering you have a python module with just the econometrics function defined, people reading the following code:
from econometrics import econometrics
econometrics()
plt.something()
wouldn't necessary understand that plt has been made available through the econometrics function call. Adding a comment would help, but still is an unnecessary extra step.
Generally speaking, doing globals within any language is wrong, and there's most of the time always a better way to do it. Within the "Zen of python", it is stated that "Explicit is better than implicit", so I believe a more elegant way would be to create a module that does the import, and then you'd import what you need from the module:
econometrics.py:
import pandas as pd
import numpy as np
import statsmodels.formula.api as smf
import statsmodels.api as sm
import matplotlib.pyplot as plt
and in your code you'd then import only what you need:
from econometrics import pd, plt
plt.something()
which would be much more elegant and explicit! Then, you'd just have to drop that file in any projects you need your mathematics modules to have all your beloved modules that need - and only them - available in your code!
Then as a step further, you could define your own python module, with a full blown setup.py, and with your econometrics.py file being a __init__.py in the econometrics package directory, to then have it installed as a python package through:
python setup.py install
at the root of your sources. So then any code you work out can be using econometrics as a python package. You might even consider making it a package on pypi!
HTH
You imported the packages into the scope of the function. If you want to use them in the global scope, you have to tell python
def importfunc():
global np
import numpy as np
importfunc()
print np.version.version
On a side note: Are you using some kind of toolchain? I'd think it would be better to use an IDE or to write a script which sets up new projects for you.
The various imports are performed when you call the function, but the names pd, np, etc are local to the function, so they can't be referenced outside the function.
I suppose you could return those names, but importing modules in a function like that makes your code a little harder for readers to follow, IMHO.

Python: Write function in module to import packages

I am trying to write a function, which is itself loaded, to quickly import a bunch of modules globally.
I thought that, essentially, loaded modules could be treated as variables so I tried:
def loadMods():
global np
import numpy as np
and when I loaded numpy (calling np) there was no problem.
What I then did was to create a separate .py file called loadTest containing
# loadTest module
# coding: utf-8
def loadMod():
global np
import numpy as np
Then attempted to import numpy using this .py file in python (2.7):
import loadTest
loadTest.loadMod()
but now when attempting calling np I get
File "<stdin>", line 1, in <module>
NameError: name 'np' is not defined
Why does this occur? Any help or alternative ways of doing this would be much appreciated. Thanks a bunch :)
Instead of making a function to do this, why not make another module? You could name it something like modules.py and put all of your imports in there:
import numpy as np
import os
import sys
...
Then, all you need to do is a wildcard import:
from modules import *
and everything will be made available.
You must first define np like that.
In loadTest:
np=None
In somewhere other
import loadTest
loadTest.loadMod()
np=loadTest.np

Python: AttributeError: 'module' object has no attribute 'randrange'

I know this could be caused by having a self-defined python file called random.py. I have searched for it, there is not file with such names, also there are no "pyc" file with this name.
I've also tried it by just typing the command in the terminal, and it seems to work! But it doesnt work when I try to compile the file!
Any idea what the problem might be?
Thanks!
import csv
import random
from numpy import *
from scipy.stats import norm
....
index = random.randrange(length)
...
First, you shouldn't do this on general principles:
from numpy import *
That shadows many built-ins like any and all with numpy versions which behave very differently. But in this case, it's also causing your other problem, because there's a numpy.random which is shadowing the main random module:
>>> import random
>>> random
<module 'random' from '/usr/lib/python3.4/random.py'>
>>> from numpy import *
>>> random
<module 'numpy.random' from '/usr/local/lib/python3.4/dist-packages/numpy/random/__init__.py'>
Note as an aside that if you're going to be generating many random numbers, using np.random instead of random is likely to be faster. (import numpy as np is the standard character-saving alias.)
It is not a best practice to import everything from modules. In this case, numpy seems to be interfering with random. When I change
from numpy import *
to
import numpy
the script runs. This would require you to reference anything you are using from numpy in the intervening code.

Using imported modules within an imported function

I have a script which runs as a standalone program, however I'd like to be able to use it as a callable function as well. Currently when i try and run it from another script, i get errors saying that certain modules are not defined/imported. For example:
NameError: global name 'exp' is not defined
Here's an example of my code that produces the error:
from PostREC3 import * ##import the required functions from the module
from numpy import array, shape, math, loadtxt, log10, vstack, arange
from scipy.integrate import quad
from pylab import all
from numpy import pi as pi
from assimulo.solvers.sundials import IDA
from assimulo.problem import Implicit_Problem
from math import exp, log10, fabs, atan, log
import pickle
import sys
results = PostREC(2,100,90,1.0,1, 1,"0",2 ) #run an imported function
output:
NameError: global name 'exp' is not defined
I've tried importing exp from within the function itself, however that doesn't change anything. As far as I'm aware, as long as I've imported them before using the function then they should be available for any other functions to use. So, is there something wrong with what I'm doing, or does this point to another error within the code itself?
O/S: Ubuntu 12.10
Python 2.7 64 bit
Import exp and any other module/function you need at the top of your PostREC3 module, not whithin a particular function.
Imports are not "global", each module needs to import everything it needs to run, even if another module already did so.

Categories