import turtle
y = -200 # Initial y value
# Turn off animation turtle.tracer(0) turtle.color("red") for x in range(10):
turtle.penup()
turtle.setposition(-200, y) turtle.pendown()
turtle.forward(400) y += 10
turtle.color("blue") for x in range(10):
turtle.penup()
turtle.setposition(-200, y) turtle.pendown()
turtle.forward(400) y += 10
turtle.color("green") for x in range(10):
turtle.penup()
turtle.setposition(-200, y) turtle.pendown()
turtle.forward(400) y += 10
turtle.color("black") for x in range(10):
turtle.penup()
turtle.setposition(-200, y) turtle.pendown()
turtle.forward(400) y += 10
turtle.update() # Ensure all of image is drawn turtle.done()
When animation is disabled with thetracerfunction, you should callupdateat the point the complete image should appear. When the tracer is active it explicitly draws the penstrokes to the screen as the turtle moves. With the tracer turned off, the programmer must ensure all the image becomes visible by calling the updatefunction. Turning the tracer off is the ultimate way to speed up Turtle graphics rendering in Python.
6.10 Other Techniques for Importing Functions and Modules
Section 6.2 introduced the two most common ways programmers use to import functions into Python code.
For the sake of completeness, we briefly examine three other importing techniques that you may encounter
6.10. OTHER TECHNIQUES FOR IMPORTING FUNCTIONS AND MODULES 186 in published Python code.
Recall that we can use thefrom. . .import. . . notation to import some of the functions that a module has to offer. This allows callers to use the base names of the functions without prepending the module name. This technique becomes unwieldy when a programmer wishes to use a large number of functions from a particular module.
The following statement:
from math import *
makes all the code in themathmodule available to the program. The*symbol is the wildcard symbol that represents “everything.” Some programmers use animportstatement like this one for programs that need to use many different functions from a module.
As we will see below, however, best Python programming practice discourages this “import everything”
approach.
This “import all” statement is in some ways the easiest to use. The mindset is, “Import everything because we may need some things in the module, but we are not sure exactly what we need starting out.”
The source code is shorter:*is quicker to type than a list of function names, and, within the program, short function names are easier to type than the longer, qualified function names. While in the short term the
“import all” approach may appear to be attractive, in the long term it can lead to problems. As an example, suppose a programmer is writing a program that simulates a chemical reaction in which the rate of the reaction is related logarithmically to the temperature. The statement
from math import log10
may cover all that this program needs from themathmodule. If the programmer instead uses from math import *
this statement imports everything from themathmodule, including a function nameddegreeswhich con- verts an angle measurement in radians to degrees (from trigonometry, 360◦=2πradians). Given the nature of the program, the worddegreesis a good name to use for a variable that represents temperature. The two words are the same, but their meanings are very different. Even though theimportstatement brings in thedegreesfunction, the programmer is free to redefinedegreesto be a floating-point variable (recall redefining theprintfunction in Section 2.3). If the program does redefinedegrees, themathmodule’s degreesfunction is unavailable if the programmer later discovers its need. Aname collisionresults if the programmer tries to use the same name for both the angle conversion and temperature representation. The same name cannot be used simultaneously for both purposes.
Most significant Python programs must import multiple modules to obtain all the functionality they need. It is possible for two different modules to provide one or more functions with the same name. This is another example of a name collision.
The names of variables and functions available to a program live in that program’snamespace. Thedir function prints a program’s namespace, and we can experiment with it in Python’s interactive interpreter:
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> x = 2
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x']
6.10. OTHER TECHNIQUES FOR IMPORTING FUNCTIONS AND MODULES 187
>>> from math import sqrt
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'sqrt', 'x']
>>> from math import *
>>> dir()
['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'x']
Observe how assigning the variable x adds the name x to the interpreter’s namespace. Importing just math.sqrtaddssqrtto the namespace. Finally, importing everything from themathmodule adds many more names. If we attempt to use any of these names in a different way, they will lose their original purpose;
for example, the following continues the above interactive sequence:
>>> help(exp)
Help on built-in function exp in module math:
exp(...) exp(x)
Return e raised to the power of x.
Now let us redefineexp:
>>> exp = None
>>> help(exp)
Help on NoneType object:
class NoneType(object)
| Methods defined here:
|
| __bool__(self, /)
| self != 0
|| __new__(*args, **kwargs) from builtins.type
| Create and return a new object. See help(type) for accurate signature.
|
| __repr__(self, /)
| Return repr(self).
If we reassign theexpname to refer toNone, we no longer can use it to computeex.
We say that the “import everything” statementpollutesthe program’s namespace. This kind of import adds many names (variables, functions, and other objects) to the collection of names managed by the program. This can cause name collisions as in the example above with the namedegrees, and it makes it more difficult to work with larger programs. When adding new functionality to such a program we must be careful not to tread on any names that already exist in the program’s namespace.
Python best programming practices discourages the use of the “import everything” statement: