Classic vs. True Division
Those arguing for this change feel that Python's division operator was flawed from the beginning, especially since Python is a common choice as a first programming language. New programmers are unlikely to recognize (automatic) floor division – try to convince a fifth grader that one divided by two is zero.
One example the proponents use to convince others is the following function:
def velocity(distance, time): rate = distance / time
Python is a dynamically-typed language, so there is no declaration of function or parameter types. In the function signature, you see no type requirements at all. Yes, the arguments can be anything; the division operation succeeds as long as the operator is sufficiently overloaded to handle the operands.
With classic division behavior, your results with a pair of floats certainly differs from that of sending in a pair of integers whereas the answer will always be correct with true division. To bridge the dichotomy, you must resolve the following intransitivity:
>>> 1 == 1.0 True >>> 2 == 2.0 True >>> 1 / 2 == 1.0 / 2.0 # classic division False
Those who aren't programmers are flabbergasted that "one divided by two is not equal to one point zero divided by two point zero!" This equality, however, does work in Python 3 using true division:
>>> from __future__ import division # 2.2+-only >>> 1 / 2 == 1.0 / 2.0 # true division True >>> 1 // 2 == 1.0 // 2.0 # floor division True
Division -Q Command-Line Option
If you do not wish to import __future__.division but want true division in all (Python 2) releases 2.2 and newer, you must use the -Qnew switch. There are several additional options when using -Q; they are summarized in the following table:
Option |
Description |
---|---|
old |
Always perform classic division |
new |
Always perform true division |
warn |
Warn against int/int (or long/long) operations |
warnall |
Warn against all uses of "/" |
Table 1: Division Operation Command-Line Options
The old and new options are obvious. The warn option looks for places where purely integer division is encountered and warns against it.
$ python -Qwarn Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 1 / 2.0 0.5 >>> 1 / 2 __main__:1: DeprecationWarning: classic int division 0
The warnall option is similar to that of warn but warns against all uses of /:
$ python -Qwarnall Python 2.5.2 (r252:60911, Feb 22 2008, 07:57:53) [GCC 4.0.1 (Apple Computer, Inc. build 5363)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> 1 / 2 __main__:1: DeprecationWarning: classic int division 0 >>> 1 / 2. __main__:1: DeprecationWarning: classic float division 0.5
One example of the use of warnall is found with the Tools/scripts/fixdiv.py script that is part of the Python source distribution. This script helps with porting efforts with code using /. See the documentation string ("docstring") for that module for more information.
Summary
So now you know what this "new" division is: It is Python's change from classic to true division in Python 3 such that the correct real quotient is returned whether the operands are integer or floating-point.
The desire to preserve some of the original functionality led to the creation of a new // floor division operator.
Table 2 summarizes the division operators and their functionality across the relevant Python releases. Note that the "3.x" column in the table also applies to Python 2.2+ with -Qnew or the import of __future__.division.
Table 2: Python Default Division Operations by Release
Operator |
2.1- |
2.2+ |
3.x |
---|---|---|---|
/ |
classic |
classic |
true |
// |
n/a |
floor |
floor |
I introduced these changes to the division operator in a Linux Journal article I wrote on the Python 2.2 release back in 2002 and detailed it further in the second edition of my book, Core Python Programming. Besides the InformIT article mentioned earlier, other additional reading includes the official "What's New in Python 2.2" document as well as the definingPEP 238, the latter of which contains more specific motivation, justification, and implementation details. You can also dig through old comp.lang.python archives for the heated debates.
Hopefully you have a much better idea of this critical change to the division operator from Python 2 to Python 3. I hope this also helps you understand why classic division was seen as a flaw that required fixing for the next generation and the continuing evolution of Python.
WESLEY J. CHUN, MSCS, is the author of Prentice Hall's bestseller, Core Python Programming, its video training course, Python Fundamentals (LiveLessons DVD), and co-author of Python Web Development with Django. In addition to being a software architect, he runs CyberWeb, a consulting business specializing in Python software engineering and technical training. He has over 25 years of programming, teaching, and writing experience, including more than a decade of Python. While at Yahoo!, he helped create Yahoo! Mail and Yahoo! People Search using Python. He holds degrees in Computer Science, Mathematics, and Music from the University of California.