I have a script which is importing lots of packages, including import numpy as np.
I have lots of scripts which need to import all of these packages (including some of my own). To make my life easier, I have a file called mysetup.py in my path to import all the packages. It includes the statement in a function called "import numpy as np".
I run "main.py". It runs the following
from mysetup import *
import_my_stuff()
np.pi()
"mysetup.py"
def import_my_stuff():
import numpy as np
return
However, I am unable to use numpy in "main.py" - this code will fail. Any suggestions as to why?
The problem you are facing is a consequence of a very important features of Python: namespaces.
https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces
https://realpython.com/python-namespaces-scope/
Basically, in your case, when you do that (numpy) import inside the (import_my_stuff) function, you are defining the code object numpy/np inside the function namespace. (scope, if you prefer).
To solve your issue (the way you are doing; not the only way), you should simply import everything at the module top level (without a function encapsulating the imports):
mysetup.py:
import numpy as np
# other modules...
main.py:
from mysetup import *
np.pi()
Imports in functions are not the best idea.
But you can just define whatever imports you need in top level code of mysetup.py
import numpy as np
and then it will be available when you import * from mysetup
from mysetup import *
print(np.pi)
I'm working on a Jupyter Notebook for my master's thesis and I'd like to keep it clean. I use a lot of functions to assign categories to groups of data.
Therefore, I've decided to put all those functions in a functions.py module which I import at the start of my notebook. My notebook has the following imports:
import sys
sys.path.append('../src/') # ugly hack to be able to import the functions module
import re
import numpy as np
import pandas as pd
import seaborn as sns
import functions as fn
One of my functions uses the "re" module for matching strings with regex. When I called the said function I get NameError: ("name 're' is not defined", 'occurred at index 0') so I figured I had to import re at the beginning of my functions.py file. This didn't change anything. So I even tried to put import re in the function body, but it wouldn't work either.
I have absolutely no idea why re doesn't work despite trying to import it everywhere.
Note: my functions worked correctly when I was defining and using them from the notebook so I know for certain it's not a bug in my function.
Solved my own issue, the answer is stupidly simple: Jupyter doesn't take into account any edits to an imported module even if you reimport it. If you make any changes to a module you have to shut down the kernel and restart it, import again and the edits will work.
In my particular case I had added import re to my functions.py but Jupyter didn't take it into account until I restarted the kernel.
In a notebook, you can use the importlib library and call importlib.reload(module) instead of restarting the kernel
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.
I often bind a module to a local name using import as, e.g. import numpy as np.
When I use np., how can I configure Eclipse so that import numpy as np shows up in the list of import suggestions (when hitting Ctrl + 1 )?
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.