Import or from for modules

I came across this in my reading. This was at the top of the script. My questions are: Why would you use “from” if you are loading all if it? I understood “from” was for importing parts of a module, example: from math import sin. Not the whole module.
This was just a something I didn’t understand. Thanks again.

import functools
from itertools import *
import operator
import pprint

from itertools import chain has the effect nearly the same as:

import itertools
chain = itertools.chain
del itertools

except it doesn’t actually create and then delete a global variable called “itertools”. After you have done this, you can just say:

for value in chain(some_values, other_values):
    ...

instead of using the fully-qualified name itertools.chain.

The wildcard import from itertools import * has the similar effect except instead of being limited to just one or two functions, it grabs all the visible functions.

So after from itertools import *, the script will have all the itertools functions available, without needing to call them by their fully-qualified names.

Although this is convenient, we generally recommend against it. It makes it hard to know what is going to be imported.

Can you list all the itertools functions without looking them up? I can’t. So I can’t tell you which existing variables, if any, will be stomped on by the wildcard import. There’s chain, and, er, islice, and … izip_longest? And … um… a bunch more.

By Steven D’Aprano via Discussions on Python.org at 24Aug2022 07:12:

The wildcard import from itertools import * has the similar effect
except instead of being limited to just one or two functions, it grabs
all the visible functions.

So after from itertools import *, the script will have all the itertools functions available, without needing to call them by their fully-qualified names.

Although this is convenient, we generally recommend against it. It makes it hard to know what is going to be imported.

Can you list all the itertools functions without looking them up? I
can’t. So I can’t tell you which existing variables, if any, will be
stomped on by the wildcard import. There’s chain, and, er, islice,
and … izip_longest? And … um… a bunch more.

Just to elaborate a bit on Steven’s remarks here:

I almost never use from module import *. Possibly absolutely never.

To my mind the only attractive case for that is when you’re doing work
based almost entirely around a particular primary module, when you might
go:

from primary_large_module import *
from module2 import this
from module3 import that

Something to note about the above: the * import is first. That way
you know what names you have overridden (if they collide). If you do the
* import later, like this:

from module2 import this
from primary_large_module import *
from module3 import that

Then unless you have intimate knowledge of primary_large_module (and
also that it will not change), you do not know that the * will not
replace the name this with something different from the *. So if I
were doing a * import, it would be first, and there would only ever be
one * import.

In practice I’ve found this circumstance never happens to me - I’m
usually pulling from various modules in a somewhat even handed manner.
But if, for example, you’re writing something whose entire purpose is,
say, a GUI, you might start with:

from tkinter import *

to get the full suite of widget names like Button etc.

However, most large modules are actually packages: things like pandas
and matplotlib and numpy all have a bunch of submodules for their
various parts, so there isn’t a single thing which is useful for a *
import anyway.

Cheers,
Cameron Simpson cs@cskk.id.au

Thanks for the explaination! Something I most likely don’t need to worry about in the long run. Could be dangerous. I have plenty of things to learn with out worring about this, at this time. I’ve been reading on pragmatic programming. Most interesting.
Thanks.

Not so much dangerous as potentially confusing.

pi = 'π'  # The Greek letter
from math import *
print(pi.upper())

Instead of printing uppercase pi Π you will get an exception because floats don’t have an upper() method. If you weren’t expecting this, it could be confusing.

But I agree that you probably don’t need to worry about wildcard imports much. They’re not very common.