Python Language
Basics
In this section, I will give you an overview of essential Python
programming concepts and language mechanics. In the next
chapter, I will go into more detail about Python’s data structures,
functions, and other built-in tools.
• Language Semantics The Python language design is distinguished by its emphasis on
readability, simplic ity, and explicitness. Some people go so far as to liken it to “executable
pseudocode.”
• Indentation, not braces Python uses whitespace (tabs or spaces) to structure code instead of
using braces as in many other languages like R, C++, Java, and Perl. Consider a for loop from a
sorting algorithm:
• for x in array:
if x < pivot:
less.append(x)
else:
greater.append(x)
A colon denotes the start of an indented code block after which all of the code must be
indented by the same amount until the end of the block.
Love it or hate it, significant whitespace is a fact of life for Python programmers, and in
my experience it can make Python code more readable than other languages I’ve used.
While it may seem foreign at first, you will hopefully grow accustomed in time.
I strongly recommend using four spaces as your default indentation and replacing tabs
with four spaces. Many text editors have a set ting that will replace tab stops with spaces
automatically (do this!). Some people use tabs or a different number of spaces, with two
spaces not being terribly uncommon. By and large, four spaces is the standard adopted
by the vast majority of Python programmers, so I recommend doing that in the absence
of a compelling reason otherwise.
As you can see by now, Python statements also do not need to be terminated by semi
colons. Semicolons can be used, however, to separate multiple statements on a single
line:
a = 5; b = 6; c = 7
Putting multiple statements on one line is generally discouraged in Python as it often
makes code less readable.
Everything is an object
An important characteristic of the Python language is the consistency of its
object model. Every number, string, data structure, function, class, module, and
so on exists in the Python interpreter in its own “box,” which is referred to as a
Python object. Each object has an associated type (e.g., string or function) and
internal data. In prac tice this makes the language very flexible, as even
functions can be treated like any other object.
Comments Any text preceded by the hash mark (pound sign) # is ignored by the
Python inter preter. This is often used to add comments to code. At times you
may also want to exclude certain blocks of code without deleting them. An easy
solution is to comment out the code:
results = []
for line in file_handle:
# keep the empty lines for now
# if len(line) == 0:
# continue
results.append(line.replace('foo', 'bar'))
Function and object method calls
You call functions using parentheses and passing zero or more
arguments, optionally assigning the returned value to a variable:
result = f(x, y, z)
g()
Almost every object in Python has attached functions, known as
methods, that have access to the object’s internal contents. You
can call them using the following syntax:
obj.some_method(x, y, z)
Functions can take both positional and keyword arguments:
result = f(a, b, c, d=5, e='foo’)
Variables and argument passing
When assigning a variable (or name) in Python, you are creating a reference to the object
on the righthand side of the equals sign. In practical terms, consider a list of integers:
In [8]: a = [1, 2, 3]
Suppose we assign a to a new variable b:
In [9]: b = a
In some languages, this assignment would cause the data [1, 2, 3] to be copied. In
Python, a and b actually now refer to the same object, the original list [1, 2, 3]
You can prove this to yourself by appending an element to a and then examining b:
In [10]: a.append(4)
In [11]: b
Out[11]: [1, 2, 3, 4]
Assignment is also referred to as binding, as we are binding a name to an object. Variable
names that have been assigned may occasion ally be referred to as bound variables.
When you pass objects as arguments to a function, new local variables are created
referencing the original objects without any copying. If you bind a new object to a vari
able inside a function, that change will not be reflected in the parent scope. It is therefore
possible to alter the internals of a mutable argument. Suppose we had the following
function:
def append_element(some_list, element):
some_list.append(element)
Then we have:
In [27]: data = [1, 2, 3]
In [28]: append_element(data, 4)
In [29]: data
Out[29]: [1, 2, 3, 4]
Dynamic references, strong types
In contrast with many compiled languages, such as Java and C++, object references in Python have no type
associated with them. There is no problem with the following:
In [12]: a = 5
In [13]: type(a)
Out[13]: int
In [14]: a = 'foo’
In [15]: type(a)
Out[15]: str
Variables are names for objects within a particular namespace; the type information is stored in the object itself.
Some observers might hastily conclude that Python is not a “typed language.” This is not true; consider this
example:
In [16]: '5' + 5
-------------------------------------------------------------------------- TypeError Traceback (most recent call last) in ()----> 1 '5' + 5
TypeError: must be str, not int
In some languages, such as Visual Basic, the string '5' might get implicitly converted (or casted) to an integer, thus
yielding 10. Yet in other languages, such as JavaScript, the integer 5 might be casted to a string, yielding the
concatenated string '55'. In this regard Python is considered a strongly typed language, which means that every
object has a specific type (or class), and implicit conversions will occur only in certain obvious circumstances, such
as the following:
In [17]: a = 4.5
In [18]: b = 2
# String formatting, to be visited later
In [19]: print('a is {0}, b is {1}'.format(type(a), type(b)))
a is <class 'float'> , b is <class 'int'>
In [20]: a / b
Out[20]: 2.25
Knowing the type of an object is important, and it’s useful to be able to write func tions that
can handle many different kinds of input. You can check that an object is an instance of a
particular type using the isinstance function:
In [21]: a = 5
In [22]: isinstance(a, int)
Out[22]: True
isinstance can accept a tuple of types if you want to check that an object’s type is among
those present in the tuple:
In [23]: a = 5; b = 4.5
In [24]: isinstance(a, (int, float))
Out[24]: True
In [25]: isinstance(b, (int, float))
Out[25]: True
The syntax s[:3] is called slicing and is implemented for many kinds of Python sequences.