why I don't need to import the supporting modules? - python

The get_square_root() function relies on the math module. To call the get_square_root() function in analysis.py, I don't need to import the math module, why is that?
# calculator.py
import math
def get_square_root(a):
return math.sqrt(a)
#analysis.py
import calculator
calculator.get_square_root(5)
Something I know about import in python (Correct me if I understood sth. wrong). When import calculator, the Python interpreter reads the whole calculator.py module, but the objects in the module not to be accessed by <ModuleName>.<ObjectName>. This is how I call the get_square_root() in analysis.py. But how the get_square_root() access math since there no math in analysis.py ?

When you run calculator in any way, math is bound in its module scope, making it accessible to get_square_root.
When you run import calculator in analysis, math is still in the module scope for get_square_root, plus calculator is bound in the scope of analysis so you can access it as calculator.math.
When you run from calculator import get_square_root in analysis, math is still in the module scope for get_square_root, but you cannot access it from analysis since calculator is not bound.

Related

How big is the overhead of importing a module within a function?

I have a Flask backend in which I import the magic module on module level, but I use it only in one function:
import magic
def wizard(filename):
return magic.from_file(filename)
As magic has a dependency to a C library which I can't install on windows and as this function is the only place where magic is used, I wondered if there is a drawback (or even an advantage) of moving the import to the function:
def wizard(filename):
import magic
return magic.from_file(filename)
Would the overhead of importing magic only matter for the first user who uses the function and later it's there for everybody? Or does Flask / Python load it again and again?

Using a dozen of global variables in iPython notebook, wrongfully-accused as duplicate [duplicate]

I am learning Python and am still a beginner, although I have been studying it for about a year now. I am trying to write a module of functions which is called within a main module. Each of the functions in the called module needs the math module to run. I am wondering if there is a way to do this without importing the math module inside the called module. Here is what I have:
main.py:
from math import *
import module1
def wow():
print pi
wow()
module1.cool()
module1.py:
def cool():
print pi
When running main.py I get:
3.14159265359
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.cool()
File "Z:\Python\module1.py", line 3, in cool
print pi
NameError: global name 'pi' is not defined
What I'm having a hard time understanding is why I get a name error when running main.py. I know that the variable pi becomes global to the main module upon import because wow can access it. I also know that cool becomes global to the main module upon import because I can print module1.cool and get <function cool at 0x02B11AF0>. So since cool is inside the global namespace of the main module, shouldn't the program first look inside the function cool for the variable pi, and then when it doesn't find it there, look inside main module for the variable pi and find it there?
The only way to get around this that I know of is to import the math module inside module1.py. I don't like the idea of that, though because it makes things more complicated and I am a fan of nice, simple code. I feel like I am close to grasping namespaces, but need help on this one. Thanks.
As the traceback shows, the problem isn't in main.py, but in module1.py:
Traceback (most recent call last):
File "Z:\Python\main.py", line 10, in <module>
module1.cool()
File "Z:\Python\module1.py", line 3, in cool
print pi
NameError: global name 'pi' is not defined
In other words, in module1, there is no global name pi, because you haven't imported it there. When you do from math import * in main.py, that just imports everything from the math module's namespace into the main module's namespace, not into every module's namespace.
I think the key thing you're missing here is that each module has its own "global" namespace. This can be a bit confusing at first, because in languages like C, there's a single global namespace shared by all extern variables and functions. But once you get past that assumption, the Python way makes perfect sense.
So, if you want to use pi from module1, you have to do the from math import * in module1.py. (Or you could find some other way to inject it—for example, module1.py could do from main import *, or main.py could do module1.pi = pi, etc. Or you could cram pi into the magic builtins/__builtin__ module, or use various other tricks. But the obvious solution is to do the import where you want it imported.)
As a side note, you usually don't want to do from foo import * anywhere except the interactive interpreter or, occasionally, the top-level script. There are exceptions (e.g., a few modules are explicitly designed to be used that way), but the rule of thumb is to either import foo or use a limited from foo import bar, baz.
"Explicit is better than implicit" is a design decision that was made by the creators of Python (launch python and run import this).
Therefore, when you run module1.cool(), Python will not look for the undefined pi in the main module.
You'll have to import the math module in explicitly whenever you want to use it - that's just how Python works.
Also, you should avoid from X import *-style imports, that's bad practice too. Here, you could do: from math import pi.
As others have said, there isn't actually a global pi in your module1. A good solution for you is this, which only imports pi once from math and explicitly ensures that the pi you're getting is the one from module1:
main.py:
import module1
def wow():
print module1.pi
wow()
module1.cool()
module1.py:
from math import pi
def cool():
print pi
The simple approach of exec (python 3) or execfile (python 2) as mentioned in the comments by #abarnert may be useful for some workflows. All that is needed is to replace the import line with:
exec( open("module1.py").read() ) # python 3
and then you can simply call the function with cool() rather than module1.cool(). Within cool(), the variable pi will behave like a global, as the OP had originally expected.
In a nutshell, this is simply hiding a function definition that would otherwise appear at the top of your main program and has both advantages and disadvantages. For large projects with multiple modules and imports, using exec (instead of a proper namespaces) is probably a mistake as you don't generally want to keep too many things within a single global namespace.
But for simple cases (like using Python as a shell script) exec gives you a simple and concise way to hide shared functions while letting them share the global namespace. Just note that in this case you might want to give extra thought to how you name your functions (e.g. use v1_cool and v2_cool to keep track of different versions since you can't do v1.cool and v2.cool).
One less obvious disadvantage of using exec here is that errors in the executed code may not display the line number of the error although you can work around this: how to get the line number of an error from exec or execfile in Python
Inside the module you could simply define from math import pi, which would only import pi from math but not the entire math module.

Importing system modules in python

Background:
I'm writing a symbolic package aimed at pypy for representing expressions and taking derivatives. Not working on simplification or anything like that at the moment, just differentiation and evaluation.
Question:
I'm writing expression classes to represent many of the functions in math (sqrt, log, exp, sin, cos, etc, etc). I have named the module that this goes in math to coincide with the module where you natural find said function. I may in the future do the same with cmath and any other module of particular mathematical interest. My module is part of a larger package ldb.algebra so the name math isn't going to collide with anything at the base namespace. However, in order to evaluate expressions I'm going to need to import the system math module inside the ldb.algebra.math module, and I can't do this from inside my math module (or any other module at the same level of package for that matter). Here's my basic path so far:
ldb/
__init__.py - empty
algebra/
__init__.py - empty
math.py
Contents of ldb/algebra/math.py as an example of the problem:
import math
my_sin = math.sin
Obviously not terribly useful but it shows the idea. I'm using python2 (or rather pypy for python2). I've found that I can get around this by creating a subpackage, a module under that say sys_math, importing math in that module and exposing the necessary functions but this seems like a lot of work and an ugly mess.
So my question is: can I get at the system math module while still having a module called ldb.algebra.math? Perhaps something funny in the __init__.py file like making the module _math and then changing the name in __init__.py somehow, or some special way to import the system module instead of myself.
My ugly solution so far:
ldb/
algebra/
extra_package/
__init__.py - empty
sys_math.py
Contents of sys_math.py:
import math
sin = math.sin
from __future__ import absolute_import
Put that at the top of your module to disable implicit relative imports. Then import math will import the built-in math module, and if you want to use relative imports, you have to do them explicitly with syntax like from . import math.

Is the expression math.sqrt() necessary?

I just started fooling around with python today; I have absolutely no idea what I'm doing. Below is a little program I wrote to display primes, which seems to be working fine and pretty quickly:
import math
N = input('List primes up to: ')
N = int(N)
for i in range(3,N,2):
for d in range(2,int(math.sqrt(i))):
if i%d==0:
break
else :
print(str(i))
The sqrt() function didn't work unless I kept in both the math.sqrt() part and the import math part. Also when I was typing stuff in the shell, it only worked if I used math.sqrt() instead of sqrt().
So...long winded question for simple thing: is there some kind of #include <math.h>-esque line I can use, for the shell and the program file (though maybe different lines for each one) so I can avoid typing in the 'math.' part every time I want to use functions from the math module? (it's a module, right?) (Because I swear I've read programs somewhere hat use sqrt() instead of math.sqrt(). But maybe not.)
Well, you can import a function directly like this:
from math import sqrt
# elsewhere
sqrt(n)
You can even import everything from the module:
from math import *
In that way you won't have to use the module prefix and say math.sqrt. However, it's recommended that you do it, to avoid possible name clashes in case two modules define a function with the same name (something that happens quite often in practice). In short, this is the preferred way:
import math
# elsewhere
math.sqrt(n)
Try:
from math import sqrt
or, if you want all of the names in the math module:
from math import *
Using either of the two methods will now allow you to just do sqrt(n) instead of math.sqrt(n).
Note however that the second method will import EVERY name in the math module. It is usually better to just import what you need (like in the first example).

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