Show the different ways to import a Python module and what each one brings into scope.
There are three forms, and the difference is which names end up in your namespace.
import math
from math import sqrt, pi
import math as m
print(math.floor(2.7)) # 2
print(sqrt(16)) # 4.0
print(m.ceil(2.1)) # 3
print(round(pi, 4)) # 3.1416The plain import binds the module name itself, so you reach everything through math.floor and so on. The from import binds the individual names, so sqrt is available directly — which is convenient, but it loses the information about where the name came from and makes it easy to collide with a local variable of the same name.
The aliased import is the compromise: it binds a short name to the whole module, which keeps the origin of the name visible while avoiding a long prefix.
The guidance that comes out of this is to prefer plain import and qualify the names, particularly in library code. It makes the origin of every name obvious and it avoids surprising collisions. The from import form is fine for a handful of well-known names, and importing a module inside a function is a useful way to keep an expensive import out of the module's start-up path.