Everything in Python Is An Object.: Unning Cripts
Everything in Python Is An Object.: Unning Cripts
RUNNING SCRIPTS
print(approximate_size(1000000000000, False))
print(approximate_size(1000000000000))
☞ Like C, Python uses == for comparison and = for assignment. Unlike C, Python does
not support in-line assignment, so there’s no chance of accidentally assigning the value
you thought you were comparing.
So what makes this if statement special? Well, modules are objects, and all modules have a built-in attribute
__name__. A module’s __name__ depends on how you’re using the module. If you import the module, then
__name__ is the module’s filename, without a directory path or file extension.
>>> humansize.__name__
'humansize'
50
But you can also run the module directly as a standalone program, in which case __name__ will be a special
default value, __main__. Python will evaluate this if statement, find a true expression, and execute the if
code block. In this case, to print two values.
1.0 TB
931.3 GiB
• PEP 257: Docstring Conventions explains what distinguishes a good docstring from a great docstring.
• Python Tutorial: Documentation Strings also touches on the subject.
• PEP 8: Style Guide for Python Code discusses good indentation style.
• Python Reference Manual explains what it means to say that everything in Python is an object, because some
people are pedants and like to discuss that sort of thing at great length.
51
CHAPTER 2. NATIVE DATATYPES
❝ Wonder is the foundation of all philosophy, inquiry its progress, ignorance its end. ❞
— Michel de Montaigne
2.1. DIVING IN
D atatypes. Set aside your first Python program for just a minute, and let’s talk about datatypes. In
Python, every value has a datatype, but you don’t need to declare the datatype of variables. How does that
work? Based on each variable’s original assignment, Python figures out what type it is and keeps tracks of
that internally.
Python has many native datatypes. Here are the important ones:
Of course, there are more types than these. Everything is an object in Python, so there are types like
module, function, class, method, file, and even compiled code. You’ve already seen some of these: modules have
names, functions have docstrings, &c. You’ll learn about classes in Classes & Iterators, and about files in
Files.
52
Strings and bytes are important enough — and complicated enough — that they get their own chapter. Let’s
look at the others first.
2.2. BOOLEANS
size is an integer, 0 is an integer, and < is a numerical operator. The result of the expression size < 0 is
always a boolean. You can test this yourself in the Python interactive shell:
53
>>> size = 1
False
>>> size = 0
False
>>> size = -1
True
Due to some legacy issues left over from Python 2, booleans can be treated as numbers. True is 1; False is
0.
54
2.3. NUMBERS
Numbers are awesome. There are so many to choose from. Python supports both integers and floating point
numbers. There’s no type declaration to distinguish them; Python tells them apart by the presence or
absence of a decimal point.
>>> type(1) ①
<class 'int'>
>>> 1 + 1 ③
2
>>> 1 + 1.0 ④
2.0
>>> type(2.0)
<class 'float'>
1. You can use the type() function to check the type of any value or variable. As you might expect, 1 is an
int.
2. Similarly, you can use the isinstance() function to check whether a value or variable is of a given type.
3. Adding an int to an int yields an int.
4. Adding an int to a float yields a float. Python coerces the int into a float to perform the addition,
then returns a float as the result.
As you just saw, some operators (like addition) will coerce integers to floating point numbers as needed.
You can also coerce them by yourself.
55
>>> float(2) ①
2.0
>>> int(2.0) ②
2
>>> int(2.5) ③
2
>>> int(-2.5) ④
-2
>>> 1.12345678901234567890 ⑤
1.1234567890123457
>>> type(1000000000000000) ⑥
<class 'int'>
1. You can explicitly coerce an int to a float by calling the float() function.
2. Unsurprisingly, you can also coerce a float to an int by calling int().
3. The int() function will truncate, not round.
4. The int() function truncates negative numbers towards 0. It’s a true truncate function, not a floor function.
5. Floating point numbers are accurate to 15 decimal places.
6. Integers can be arbitrarily large.
☞ Python 2 had separate types for int and long. The int datatype was limited by
sys.maxint, which varied by platform but was usually 232-1. Python 3 has just one
integer type, which behaves mostly like the old long type from Python 2. See PEP
56
>>> 11 / 2 ①
5.5
>>> 11 // 2 ②
5
>>> −11 // 2 ③
−6
>>> 11.0 // 2 ④
5.0
>>> 11 ** 2 ⑤
121
>>> 11 % 2 ⑥
1
1. The / operator performs floating point division. It returns a float even if both the numerator and
denominator are ints.
2. The // operator performs a quirky kind of integer division. When the result is positive, you can think of it
as truncating (not rounding) to 0 decimal places, but be careful with that.
3. When integer-dividing negative numbers, the // operator rounds “up” to the nearest integer. Mathematically
speaking, it’s rounding “down” since −6 is less than −5, but it could trip you up if you were expecting it to
truncate to −5.
4. The // operator doesn’t always return an integer. If either the numerator or denominator is a float, it will
still round to the nearest integer, but the actual return value will be a float.
5. The ** operator means “raised to the power of.” 112 is 121.
6. The % operator gives the remainder after performing integer division. 11 divided by 2 is 5 with a remainder
of 1, so the result here is 1.
☞ In Python 2, the / operator usually meant integer division, but you could make it
behave like floating point division by including a special directive in your code. In
Python 3, the / operator always means floating point division. See PEP 238 for
details.
57
2.3.3. FRACTIONS
Python isn’t limited to integers and floating point numbers. It can also do all the fancy math you learned in
high school and promptly forgot about.
Fraction(1, 3)
>>> x * 2 ③
Fraction(2, 3)
>>> fractions.Fraction(6, 4) ④
Fraction(3, 2)
>>> fractions.Fraction(0, 0) ⑤
Traceback (most recent call last):
ZeroDivisionError: Fraction(0, 0)
2.3.4. TRIGONOMETRY
58
>>> import math
>>> math.pi ①
3.1415926535897931
>>> math.sin(math.pi / 2) ②
1.0
>>> math.tan(math.pi / 4) ③
0.99999999999999989
1. The math module has a constant for π, the ratio of a circle’s circumference to its diameter.
2. The math module has all the basic trigonometric functions, including sin(), cos(), tan(), and variants like
asin().
3. Note, however, that Python does not have infinite precision. tan(π / 4) should return 1.0, not
0.99999999999999989.
Zero values
are false,
and non-
zero values
are true.
59
>>> def is_it_true(anything): ①
... if anything:
... else:
...
>>> is_it_true(1) ②
yes, it's true
>>> is_it_true(-1)
>>> is_it_true(0)
>>> is_it_true(0.1) ③
yes, it's true
>>> is_it_true(0.0)
1. Did you know you can define your own functions in the Python interactive shell? Just press ENTER at the end
of each line, and ENTER on a blank line to finish.
2. In a boolean context, non-zero integers are true; 0 is false.
3. Non-zero floating point numbers are true; 0.0 is false. Be careful with this one! If there’s the slightest
rounding error (not impossible, as you saw in the previous section) then Python will be testing
0.0000000000001 instead of 0 and will return True.
4. Fractions can also be used in a boolean context. Fraction(0, n) is false for all values of n. All other
fractions are true.
60