For most pruposes they’re fairly similar. You still have to load the module. For one or two names you’ll be using repeatedly throughout your code using from module import x can save you a fair bit of typing and reudce overly long variable names keeping your code legible.
If you tried to pull numerous names though it can make it a nightmare for anyone who has to read your code since its not always clear what your names refer to (a module alias, e.g. math.fsum makes it easier to keep track of).
For a bit more discussion-
I’m not sure the module gets loaded. If it did then we could call other methods…
>>> from random import choice
>>> random.randint(1,6)
Traceback (most recent call last):
File "<pyshell#221>", line 1, in <module>
random.randint(1,6)
NameError: name 'random' is not defined
>>>
From my understanding (which is second hand info at best) the whole module gets parsed anyway so I just meant it as there’s no speed or memory benefits to using from. You’re quite right there’s no alias to the module itself so the name random isn’t a valid reference just because you imported something from the random module which is an important point.
I would agree with that. It has to import the module but then appears to release it once the method(s) are parsed into the namespace. We’re on the same footing as far as any good info is concerned.
“from library import always_three” example is super useful. How does this function work with Jupyter Notebook files? For an example when I am in an ipynb file , how do I import a module/method from another ipynb inside or outside the current folder location?
Generally you’d import from a .py file (or a package based on the same) which is fairly straightforward. Since the notebooks are third party and set up differently I don’t think you can import from them directly. Have a web search to see if anyone has worked around that (quite possible that someone has created a tool to do so), or if that doesn’t work, save the .ipynb files as .py files and import from them instead.
Other than what you suggest, aren’t there extra subject matter which I need to research earlier than moving into projects. I’m so excited to work in project but I sense like there are more subjects to learn.
I have a question about the way this exercise was presented (not about the concepts involved themselves):
The first instruction said to define a function always_three with no parameters that returned the value 3.
I typed in the following:
def always_three():
return 3
When I ran it a message came back asking "Did you define a function always_three()?
The answer is actually “Yes, I did”, but the box for the first instruction was left unchecked and I could not proceed. It turns out that the function was already defined in the library that was to be imported. Given that, why did the instruction ask me to define it myself and why did the error message seem to indicate that I had not when in fact I had? This kind of problem has occurred in some previous lessons as well. I may be missing something here. If so, please explain. Since I actually understood the concept it was frustrating to not be able to get past this point without substituting the correct solution provided.
The above has been helpful, but I still have a couple of questions.
Are there any performance benefits to using ‘from module import object’ over ‘import module’ ?
What’s the difference between ‘import module’ and ‘from module import *’ ? The second isn’t recommended but to me it appears to be the same thing - import everything from module.
Doubtful there are any performance benefits, in terms of space complexity. Importing from just makes it easier to write the function calls.
from math import pi as PI
Now we can write the constant without the math. prefix. Even while it looks like we only import pi one suspects the entire module is in the global namespace, along with a secondary reference to the function (another variable).
The functions will still run the same, as well, so it’s difficult to see how this will improve performance.
As for using the splat operator, that will end up creating a gazillion new variables so proves itself as redundant.
import module
moves the entire module into the global namespace but with no references to its functions.
Yeah the entire module is loaded even if you pull a single name with from x import y, you can find loaded modules with import sys; print(sys.modules).
There is a minute additional cost for math.PI versus a localised PI as you must load a name and then load an attribute name. For extremely heavy use inside a function this might make a difference but it’s high risk premature optimisation. @welfrosti standard advice would be to choose the readable option, do not change without profiling and localise the name only when necessary.