Python Handbook 1
Python Handbook 1
COM
PYTHON
HANDBOOK
Table of Contents
i. Introduction to PythonInstalling
Python
ii. Running Python programsPython 2 vs
Python 3
iii. The basics of working with PythonData types
iv. Operators
v. The Ternary OperatorStrings
vi. Booleans Numbers
ConstantsEnums User
Input
vii. Control statementsLists
viii. Tuples DictionariesSets
x. ClassesModules
xi. The Python Standard LibraryThe PEP8 Python
style guideDebugging
xii. Variables scope
xiii. Accept arguments from the command lineLambda functions
xiv. Recursion Nested functions
Closures Decorators Docstrings
Introspection Annotations
Exceptions
xv. The with statement
xvi. Installing 3rd party packages using pipList comprehensions
xvii. Polymorphism Operator Overloading
Virtual Environments Conclusion
1
Introduction to Python
Python is literally eating the programming world. It is growing in
popularity and usage in ways that are prettymuch unprecedented in the
history of computers.
2
It is also appreciated by professionals across many different fields.
This has pros and cons. In particular we can mention that you write
programs faster, but on the other hand you have less help from the tools
to prevent possible bugs and you will find out about some kinds of
issues only by executing the program at runtime.
3
Starting with Python is very easy. All you need is to install the official
package from python.org, for Windows, macOS or Linux, and you're
ready to go.
If you are new to programming, in the following posts Iwill guide you to
go from zero to becoming a Python programmer.
Lower level languages like C++ and Rust might be great for expert
programmers, but daunting to begin, and they take a long time to
master. Python, on the other hand, is a programming language for
programmers, of course, but also for the non- programmers. The
students, the people doing theirday job with Excel, the scientists.
4
The language everyone interested in codingshould learn
first.
5
Installing Python
Go to https://www.python.org, choose the Downloads menu, choose
your operating system and a panel witha link to download the official
package will appear:
Make sure you follow the specific instructions for your operating system.
On macOS you can find a detailed guide on
https://flaviocopes.com/python-installation-macos/.
6
Running Python
programs
There are a few different ways to run Pythonprograms.
If you open your terminal and type python , you willsee a screen like
this:
Notice the >>> symbol, and the cursor after that. Youcan type any
Python code here, and press the enter key to run it.
name = "Flavio"
7
print(name)
Note: in the REPL, you can also just type name , press the enter key
and you'll get the value back. But in a program, you are not going
to see any output if you do so - you need to use
print() instead.
You can access the same interactive prompt using theIDLE application
that's installed by Pythonautomatically:
8
This might be more convenient for you because with the mouse you can
move around and copy/paste moreeasily than with the terminal.
Those are the basics that come with Python by default. However I
recommend to install IPython, probably the best command line REPL
application youcan find.
Install it with
Make sure the pip binaries are in your path, then run
ipython :
9
and then run it with python program.py
In this case the program is executed as a whole, not one line at a time.
And that's typically how we run programs.
10
Then I can set execution permission on the file:
./program.py
This is especially useful when you write scripts thatinteract with the
terminal.
11
After installing this extension you will have Pythoncode autocompletion
and error checking, automaticformatting and code linting with pylint ,
and some special commands, including:
Python: Run Python File in Terminal to run the current file in the
terminal:
12
Python: Run Current File in Python InteractiveWindow:
and many more. Just open the command palette(View -> Command
Palette, or Cmd-Shift-P) and type
python to see all the Python-related commands:
13
Another way to easily run Python code is to use repl.it, a very nice
website that provides a coding environment you can create and run
your apps on, in any language, Python included:
14
and you will be immediately shown an editor with a
main.py file, ready to be filled with a lot of Pythoncode:
Once you have some code, click "Run" to run it on theright side of the
window:
15
I think repl.it is handy because:
you can easily share code just by sharing the linkmultiple people
can work on the same code
it can host long-running programsyou can install
packages
it provides you a key-value database for morecomplex
applications
16
Python 2 vs Python 3
One key topic to talk about, right from the start, is the Python 2 vs Python
3 discussion.
Many programs are still written using Python 2, and organizations still
actively work on those, because the migration to Python 3 is not trivial
and those programs would require a lot of work to upgrade those
programs. And large and important migrations always introduce new
bugs.
But new code, unless you have to adhere to rules set by your
organization that forces Python 2, should always be written in Python 3.
17
The basics of workingwith
Python
Variables
We can create a new Python variable by assigning avalue to a label,
using the = assignment operator.
label:
name = "Roger"
age = 8
underscore character. It can't start with a number. These are all valid
variable names:
name1
AGE
aGE
a11111
my_name
_name
18
123
test!
name%
Expressions andstatements
We can expression any sort of code that returns a value. For example
1 + 1
"Roger"
name = "Roger"
print(name)
19
name = "Roger"; print(name)
Comments
In a Python program, everything after a hash mark isignored, and
considered a comment:
Indentation
Indentation in Python is meaningful. You cannot
name = "Flavio"
print(name)
In this case, if you try to run this program you would get a
IndentationError: unexpected indent error, because indenting has
a special meaning.
20
Data types
Python has several built-in types.
name = "Roger"
name = "Roger"
type(name) == str #True
Or using isinstance() :
name = "Roger"
isinstance(name, str) #True
We used the str class here, but the same works forother data types.
21
age = 1
type(age) == int #True
fraction = θ.1
type(fraction) == float #True
name = "Flavio"
age = 2θ
You can also create a variable of a specific type by using the class
constructor, passing a value literal or avariable name:
name = str("Flavio")
anotherName = str(name)
You can also convert from one type to another by using the class
constructor. Python will try to determine the correct value, for example
extracting a number from a string:
age = int("2θ")
print(age) #2θ
fraction = θ.1
intFraction = int(fraction)
print(intFraction) #θ
22
This is called casting. Of course this conversion mightnot always
work depending on the value passed. If
you write you'll get test instead of 2θ in the above string,
a ValueError: invalid literal for int()
Those are just the basics of types. We have a lot moretypes in Python:
for complex
complex numbersfor booleans
forlist
lists for tuples
bool
for ranges
tuple
range
fordict
dictionariesfor sets
set
and more!
23
Operators
Python operators are symbols that we use to runoperations upon
values and variables.
Assignment operator
The assignment operator is used to assign a value toa variable:
age = 8
age = 8
anotherVariable = age
24
Arithmetic operators
Python has a number of arithmetic operators: + , – ,
C , / (division), % (remainder), CC
1 + 1 #2
2 – 1 #1
2 C 2 #4
4 / 2 #2
4 % 3 #1
4 CC 2 #16
4 // 2 #2
print(–4) #–4
+=
–=
C=
/=
%=
..and so on
25
Example:
age = 8
age += 1
# age is now 9
Comparison operators
Python defines a few comparison operators:
==
!=
>
<
>=
<=
You can use those operators to get a boolean value( True or False )
depending on the result:
a = 1
b = 2
a == b #False
a != b #True
a > b #False
a <= b #True
Boolean operators
Python gives us the following boolean operators:
not
and
or
26
When working with True or False attributes, those work like logical
AND, OR and NOT, and are often used in the if conditional
expression evaluation:
condition1 = True
condition2 = False
print(θ or 1) ## 1
print(False or 'hey') ## 'hey'
print('hi' or 'hey') ## 'hi'
print([] or False) ## 'False'
print(False or []) ## '[]'
27
print(θ and 1) ## θ
print(1 and θ) ## θ
print(False and 'hey') ## False
print('hi' and 'hey') ## 'hey'
print([] and False ) ## []
print(False and [] ) ## False
Bitwise operators
Some operators are used to work on bits and binarynumbers:
Bitwise operators are rarely used, only in very specificsituations, but they are
worth mentioning.
is and in
is is called the identity operator. It is used to compare two
objects and returns true if both are the same object. More on objects
later.
28
The Ternary Operator
The ternary operator in Python allows you to quicklydefine a
conditional.
Let's say you have a function that compares an age variable to the
18 value, and return True or Falsedepending on the result.
Instead of writing:
def is_adult(age):
if age > 18:
return True
else:
return False
def is_adult(age):
return True if age > 18 else False
First you define the result if the condition is True, then you evaluate the
condition, then you define the result ifthe condition is false:
29
Strings
A string in Python is a series of characters enclosedinto quotes or
double quotes:
"Roger"
'Roger'
name = "Roger"
operator:
name = "Roger"
name += " is a good dog"
class constructor:
str(8) #"8"
30
print("Roger is " + str(8) + " years old") #Roger i
print("""Roger is
years old
""")
print('''
Roger is
years old
''')
31
startsswith() to check if the string starts with aspecific
substring
endswith() to check if the string ends with aspecific
substring
replace() to replace a part of a string
split() to split a string on a specific characterseparator
strip() to trim the whitespace from a string
join() to append new letters to a string
find() to find the position of a substringand many
more.
name = "Roger"
print(name.lower()) #"roger"
print(name) #"Roger"
name = "Roger"
print(len(name)) #5
name = "Roger"
print("ger" in name) #True
32
Escaping is a way to add special characters into astring.
For example, how do you add a double quote into astring that's
wrapped into double quotes?
name = "Roger"
"Ro"Ger" will not work, as Python will think the stringends at "Ro" .
The way to go is to escape the double quote inside thestring, with the
\ backslash character:
name = "Ro\"ger"
This applies to single quotes too \' , and for special formatting
characters like \t for tab, \n for new lineand \\ for the backslash.
Given a string, you can get its characters using squarebrackets to get a
specific item, given its index, starting from 0:
name = "Roger"
name[θ] #'R'
name[1] #'o'
name[2] #'g'
name = "Roger"
name[–1] #"r"
33
You can also use a range, using what we call slicing:
name = "Roger"
name[θ:2] #"Ro"
name[:2] #"Ro"
name[2:] #"ger"
34
Booleans
Python provides the bool type, which can have two values: True
done = False
done = True
statements:
done = True
if done:
# run some code here
else:
# run some other code
When evaluating a value for True or False , if the value is not a bool
done = True
type(done) == bool #True
35
Or using isinstance() , passing 2 arguments: thevariable, and
the bool class:
done = True
isinstance(done, bool) #True
The global any() function is also very useful when working with
booleans, as it returns True if any of thevalues of the iterable (list, for
example) passed as argument are True :
book_1_read = True
book_2_read = False
ingredients_purchased = True
meal_cooked = False
36
Numbers
Numbers in Python can be of 3 types: int , float
and complex .
Integer numbers
Integer numbers are represented using the int
age = 8
age = int(8)
fraction = θ.1
37
fraction = float(θ.1)
global function:
Complex numbers
Complex numbers are of type complex . You can define
complexNumber = 2+3j
complexNumber = complex(2, 3)
Once you have a complex number, you can get its realand imaginary
part:
complexNumber.real #2.θ
complexNumber.imag #3.θ
38
You can perform arithmetic operations on numbers,using the
arithmetic operators: + , – , C , / (division), % (remainder),
CC (exponentiation) and
// (floor division):
1 + 1 #2
2 – 1 #1
2 C 2 #4
4 / 2 #2
4 % 3 #1
4 CC 2 #16
4 // 2 #2
+=
–=
C=
/=
%=
..and so on
age = 8
age += 1
Built-in Functions
There are 2 built-in functions that help with numbers:
39
round(θ.12) #θ
round(θ.12, 1) #θ.1
40
Constants
Python has no way to enforce a variable to be aconstant.
class Constants(Enum):
WIDTH = 1θ24
HEIGHT = 256
WIDTH = 1θ24
No one will prevent to overwrite this value, and Pythonwill not stop it.
41
Enums
Enums are readable names that are bound to aconstant value.
class State(Enum):
INACTIVE = θ
ACTIVE = 1
print(State.ACTIVE)
42
list(State) # [<State.INACTIVE: θ>, <State.ACTIVE:
len(State) # 2
43
User Input
In a Python command line application you can displayinformation to the user
using the print() function:
name = "Roger"
print(name)
This approach gets input at runtime, meaning the program will stop
execution and will wait until the user types something and presses the
enter key.
You can also do more complex input processing and accept input at
program invocation time, and we'll see how to do that later on.
44
Control statements
What's interesting to do with booleans, andexpressions that return a
boolean in particular, is that we can make decisions and take different
roads depending on their True or False value.
condition = True
if condition == True:
# do something
When the condition test resolves to True , like in theabove case, its
block gets executed.
condition = True
if condition == True:
print("The condition")
print("was true")
The block can be formed by a single line, or multiple lines as well, and
it ends when you move back to the previous indentation level:
45
condition = True
if condition == True:
print("The condition")
print("was true")
condition = True
if condition == True:
print("The condition")
print("was True")
else:
print("The condition")
print("was False")
condition = True
name = "Roger"
if condition == True:
print("The condition")
print("was True")
elif name == "Roger":
print("Hello Roger")
else:
print("The condition")
print("was False")
46
The second block in this case is executed if
condition is False , and the name variable value is"Roger".
condition = True
name = "Roger"
if condition == True:
print("The condition")
print("was True")
elif name == "Roger":
print("Hello Roger")
elif name == "Syd":
print("Hello Syd")
elif name == "Flavio":
print("Hello Flavio")
else:
print("The condition")
print("was False")
Example:
a = 2
result = 2 if a == θ else 3
print(result) # 3
47
Lists
Lists are an essential Python data structure.
The allow you to group together multiple values andreference them all with a
common name.
For example:
items = []
items[θ] # "Roger"
items[1] # 1
items[3] # True
48
Using the same notation you can change the valuestored at a
specific index:
items[θ] = "Roger"
items.index(θ) # "Roger"
items.index(1) # 1
items[–1] # True
items[θ:2] # ["Roger", 1]
items[2:] # ["Syd", True]
len(items) #4
method:
items.append("Test")
49
items.extend(["Test"])
items += ["Test"]
items.remove("Test")
#or
items.extend(["Test1", "Test2"])
50
To add multiple items at a specific index, you need touse slices:
items.sort()
Tip: sort() will only work if the list holds values that can be
compared. Strings and integers for example can't be
compared, and you'll get an error like TypeError: '<' not
items.sort(key=str.lower)
instead.
Sorting modifies the original list content. To avoid that,you can copy
the list content using
itemscopy = items[:]
print(sorted(items, key=str.lower))
that will return a new list, sorted, instead of modifyingthe original list.
51
52
Tuples
Tuples are another fundamental Python data structure.
They allow you to create immutable groups of objects. This means that
once a tuple is created, it can't be modified. You can't add or remove
items.
They are created in a way similar to lists, but using parentheses instead
of square brackets:
A tuple is ordered, like a list, so you can get its valuesreferencing an index
value:
names[θ] # "Roger"
names[1] # "Syd"
items.index("Roger") # θ
items.index("Syd") # 2
names[–1] # True
function:
53
len(names) # 2
Get the number of items in a tuple using the len() global function,
the same we used to get the length ofa string:
len(names) #2
sorted(names)
You can create a new tuple from existing tuples usingthe + operator:
54
Dictionaries
Dictionaries are a very important Python data structure.
The key can be any immutable value like a string, a number or a tuple.
The value can be anything you want.
dog['name'] # 'Roger'
dog['age'] # 8
dog['name'] = 'Syd'
55
And another way is using the get() method, whichhas an option to
add a default value:
dog.get('name') # 'Roger'
dog.get('test', 'default') # 'default'
The pop() method retrieves the value of a key, andsubsequently deletes the
item from the dictionary:
dog.pop('name') # 'Roger'
dog.popitem()
operator:
constructor:
Get the values using the values() method, and thekey/value pairs
tuples using the items() method:
56
print(list(dog.values()))
# ['Roger', 8]
print(list(dog.items()))
# [('name', 'Roger'), ('age', 8)]
Get a dictionary length using the len() global function, the same we
used to get the length of astring or the items in a list:
len(dog) #2
You can add a new key/value pair to the dictionary inthis way:
statement:
dogCopy = dog.copy()
57
Sets
Sets are another important Python data structure.
We can say they work like tuples, but they are not ordered, and they are
mutable. Or we can say they work like dictionaries, but they don't have
keys.
58
set1 = {"Roger", "Syd"}
set2 = {"Roger"}
global function:
You can get a list from the items in a set by passingthe set to the
list() constructor:
59
Functions
A function lets us create a set of instructions that we can run when
needed.
def hello():
print('Hello!')
To run this function, we must call it. This is the syntax to call the function:
hello()
60
def hello(name):
print('Hello ' + name + '!')
hello('Roger')
hello()
#Hello my friend!
hello('Roger', 8)
61
Parameters are passed by reference. All types in Python are objects but
some of them are immutable, including integers, booleans, floats,
strings, and tuples. This means that if you pass them as parameters
and you modify their value inside the function, the new value is not
reflected outside of the function:
def change(value):
value = 2
val = 1
change(val)
print(val) #1
If you pass an object that's not immutable, and you change one of its
properties, the change will be reflected outside.
def hello(name):
print('Hello ' + name + '!')
return name
def hello(name):
print('Hello ' + name + '!')
return
62
We can have the return statement inside a conditional, which is a
common way to end a function if a starting condition is not met:
def hello(name):
if not name:
return
print('Hello ' + name + '!')
def hello(name):
print('Hello ' + name + '!')
return name, 'Roger', 8
63
Objects
Everything in Python is an object.
Even values of basic primitive types (integer, string, float..) are objects.
Lists are objects, tuples,dictionaries, everything.
Objects have attributes and methods that can be accessed using the
dot syntax.
age = 8
age now has access to the properties and methodsdefined for all
int objects.
print(age.real) # 8
print(age.imag) # θ
print(age.bit_length()) #4
items = [1, 2]
items.append(3)
items.pop()
64
The methods depend on the type of value.
id(age) # 14θ17θθ65725376
If you assign a different value to the variable, its address will change,
because the content of the variable has been replaced with another
value stored in another location in memory:
age = 8
print(id(age)) # 14θ5359186718θ8
age = 9
print(id(age)) # 14θ53591867184θ
But if you modify the object using its methods, theaddress stays
the same:
items = [1, 2]
print(id(items)) # 14θθ9371359392θ
items.append(3)
print(items) # [1, 2, 3]
print(id(items)) # 14θθ9371359392θ
65
The address only changes if you reassign a variable toanother value.
Some objects are mutable, some are immutable. This depends on the
object itself. If the object providesmethods to change its content, then
it's mutable. Otherwise it's immutable. Most types defined by Python are
immutable. For example an int is immutable. There are no methods to
change its value. If you increment the value using
age = 8
age = age + 1
#or
age += 1
and you check with id(age) you will find that age points to a
different memory location. The originalvalue has not mutated, we
switched to another value.
66
Loops
Loops are one essential part of programming.
while loops
while loops are defined using the while keyword, and they repeat
their block until the condition isevaluated as False :
condition = True
while condition == True:
print("The condition is True")
condition = True
while condition == True:
print("The condition is True")
condition = False
In this case, the first iteration is ran, as the condition test is evaluated to
True , and at the second iteration the condition test evaluates to False , so
the control goes to the next instruction, after the loop.
67
It's common to have a counter to stop the iterationafter some
number of cycles:
count = θ
while count < 1θ:
print("The condition is True")count
= count + 1
for loops
Using for loops we can tell Python to execute a block for a pre-
determined amount of times, up front, and without the need of a
separate variable and conditional to check its value.
items = [1, 2, 3, 4]
for item in items:
print(item)
function:
To get the index, you should wrap the sequence intothe enumerate()
function:
68
items = [1, 2, 3, 4]
for index, item in enumerate(items):
print(index, item)
continue stops the current iteration and tells Pythonto execute the
next one.
break stops the loop altogether, and goes on with thenext instruction
after the loop end.
items = [1, 2, 3, 4]
for item in items:
if item == 2:
continue
print(item)
items = [1, 2, 3, 4]
for item in items:
if item == 2:
break
print(item)
69
Classes
Defining new objects in Python usingclasses
class <class_name>:
# my class
class Dog:
# the Dog class
class Dog:
# the Dog class
def bark(self):
print('WOF!')
70
We create an instance of a class, an object, using thissyntax:
roger = Dog()
If you run
print(type(roger))
class Dog:
# the Dog class
def init (self, name, age):
self.name = name
self.age = age
def bark(self):
print('WOF!')
roger = Dog('Roger', 8)
print(roger.name) # 'Roger'
print(roger.age) # 8
roger.bark() # 'WOF!'
71
We can create an Animal class with a method
walk() :
class Animal:
def walk(self):
print('Walking..')
class Dog(Animal):
def bark(self):
print('WOF!')
roger = Dog()
roger.walk() # 'Walking..'
roger.bark() # 'WOF!'
72
Modules
Every Python file is a module.
You can import a module from other files, and that's the base of any
program of moderate complexity, as it promotes a sensible organization
and code reuse.
In the typical Python program, one file acts as theentry point. The
other files are modules and expose functions that we can call from other
files.
def bark():
print('WOF!')
import dog
dog.bark()
Or, we can use the from .. import syntax and callthe function
directly:
bark()
73
The second strategy lets us pick the things we need.
Now you can choose, you can import dog from lib :
dog.bark()
bark()
74
The Python StandardLibrary
Python exposes a lot of built-in functionality through its
standard library.
You can find the full list of standard library modules here:
https://docs.python.org/3/library/index.html
formath
math utilities
for regular
re expressionsto work with
JSON
json
to work
datetime with datesto use SQLite
for Operating
sqlite3 System utilities
os
utilities
statistics
to perform
requests HTTP network requeststo create HTTP
servers
http
to manage URLs
urllib
Let's introduce how to use a module of the standard library. You already
know how to use modules you create, importing from other files in the
program folder.
Well that's the same with modules provided by the standard library:
75
import math
math.sqrt(4) # 2.θ
or
sqrt(4) # 2.θ
76
The PEP8 Python styleguide
When you write code, you should adhere to the conventions of the
programming language you use.
If you learn the right naming and formatting conventions right from the
start, it will be easier toread code written by other people, and people
will find your code easier to read.
Python defines its conventions in the PEP8 style guide. PEP stands for
Python Enhancement Proposals and it's the place where all Python
language enhancements and discussions happen. There are a lot of
PEP proposals, all available at https://www.python.org/dev/peps/.
PEP8 is one of the first ones, and one of the most important, too. It
defines the formatting and also some rules on how to write Python in a
"pythonic" way.
77
Functions, variable names and file names are lowercase, with
underscores between words (snake_case)
Class names are capitalized, separate words arewritten with the
capital letter too, (CamelCase) Package names are lowercase
and do not haveunderscores between words
Variables that should not change (constants) arewritten in
uppercase
Variable names should be meaningful
Add useful comments, but avoid obviouscomments
Add spaces around operators
Do not use unnecessary whitespaceAdd a blank line
before a function
Add a blank line between methods in a class Inside
functions/methods, blank lines can be usedto separate
related blocks of code to helpreadability
78
Debugging
Debugging is one of the best skills you can learn, as itwill help you in
many difficult situations.
Every language has its debugger. Python has pdb ,available through
the standard library.
breakpoint()
When the Python interpreter hits a breakpoint in your code, it will stop,
and it will tell you what is the next instruction it will run.
You can type the name of any variable to inspect its value.
You can press n to step to the next line in the current function. If the code
calls functions, the debugger doesnot get into them, and consider them
"black boxes".
You can press s to step to the next line in the current function. If the
next line is a function, the debugger goes into that, and you can then
run one instruction of that function at a time.
79
You can press q to stop the execution of the program.
80
Variables scope
When you declare a variable, that variable is visible in parts of your
program, depending on where you declare it.
age = 8
def test():
print(age)
print(age) # 8
test() # 8
def test():
age = 8
print(age)
test() # 8
print(age)
# NameError: name 'age' is not defined
81
Accept arguments fromthe
command line
Python offers several ways to handle arguments passed when we
invoke the program from thecommand line.
python <filename>.py
You can pass additional arguments and options whenyou do so, like
this:
list:
import sys
print(len(sys.argv))
print(sys.argv)
The sys.argv list contains as the first item the nameof the file that
was ran, e.g. ['main.py'] .
82
This is a simple way, but you have to do a lot of work. You need to
validate arguments, make sure their type is correct, you need to print
feedback to the user ifthey are not using the program correctly.
import argparse
parser = argparse.ArgumentParser(
description='This program prints the name of my
)
import argparse
parser = argparse.ArgumentParser(
description='This program prints a color HEX va
)
args = parser.parse_args()
print(args.color) # 'red'
83
➜ python python program.py
usage: program.py [–h] –c color
program.py: error: the following arguments are requ
84
Lambda functions
Lambda functions (also called anonymous functions) are tiny functions
that have no name and only have one expression as their body.
lambda a, b : a C b
multiply = lambda a, b : a C b
print(multiply(2, 2)) # 4
85
The utility of lambda functions comes when combined with other
Python functionality, for example incombination with map() , filter()
and reduce() .
86
Recursion
A function in Python can call itself. That's what recursion is. And it can
be pretty useful in many scenarios.
3! = 3 C 2 C 1 = 6
4! = 4 C 3 C 2 C 1 = 24
5! = 5 C 4 C 3 C 2 C 1 = 12θ
def factorial(n):
if n == 1: return 1
return n C factorial(n–1)
print(factorial(3)) # 6
print(factorial(4)) # 24
print(factorial(5)) # 12θ
87
Recursion is helpful in many places, and it helps us simplify our code
when there's no other optimal way to do it, so it's good to know this
technique.
88
Nested functions
Functions in Python can be nested inside otherfunctions.
This is useful to create utilities that are useful to afunction, but not
useful outside of it.
You might ask: why should I be "hiding" this function, ifit does not
harm?
Here is an example:
def talk(phrase):
def say(word):
print(word)
If you want to access a variable defined in the outer function from the
inner function, you first need to declare it as nonlocal :
89
def count():
count = θ
def increment():
nonlocal count
count = count + 1
print(count)
increment()
count()
90
Closures
If you return a nested function from a function, that nested function has
access to the variables defined in that function, even if that function is
not active any more.
def counter():
count = θ
def increment():
nonlocal count
count = count + 1
return count
return increment
increment = counter()
print(increment()) # 1
print(increment()) # 2
print(increment()) # 3
We return the increment() inner function, and that has still access to
the state of the count variable even though the counter() function has
ended.
91
Decorators
Decorators are a way to change, enhance or alter in any way how a
function works.
Example:
@logtime
def hello():
print('hello!')
def logtime(func):
def wrapper():
# do something before
val = func()
# do something after
return val
return wrapper
92
Docstrings
Documentation is hugely important, not just to communicate to other
people what is the goal of a function/class/method/module, but also to
yourself.
When you'll come back to your code 6 or 12 months from now, you might
not remember all the knowledge you are holding in your head, and
reading your code and understanding what it is supposed to do, will be
much more difficult.
# this is a comment
def increment(n):
"""Increment a number"""
return n + 1
93
class Dog:
"""A class representing a dog"""
def init (self, name, age):
"""Initialize a new dog"""
self.name = name
self.age = age
def bark(self):
"""Let the dog bark"""
print('WOF!')
"""Dog module
This module does ... bla bla bla and provides the f
– Dog
...
"""
class Dog:
"""A class representing a dog"""
def init (self, name, age):
"""Initialize a new dog"""
self.name = name
self.age = age
def bark(self):
"""Let the dog bark"""
print('WOF!')
94
def increment(n):
"""Increment
a number
"""
return n + 1
increment(n)
Increment
a number
95
Introspection
Functions, variables and objects can be analyzedusing
introspection.
def increment(n):
return n + 1
print(increment)
or an object:
class Dog():
def bark(self):
print('WOF!')
roger = Dog()
print(roger)
96
print(type(increment))
# <class 'function'>
print(type(roger))
# <class ' main .Dog'>
print(type(1))
# <class 'int'>
print(type('test'))
# <class 'str'>
The dir() global function lets us find out all themethods and
attributes of an object:
print(dir(roger))
# [' class ', ' delattr ', ' dict ', ' dir
print(id(roger)) # 14θ227518θ93θ24
print(id(1)) # 14θ227521172384
97
Annotations
Python is dynamically typed. We do not have to specify the type of a
variable or function parameter, or a function return value.
def increment(n):
return n + 1
count: int = θ
Python will ignore those annotations. A separate tool called mypy can be
run standalone, or integrated by IDE like VS Code or PyCharm to
automatically check for type errors statically, while you are coding, and
it will help you catch type mismatch bugs before even running the code.
A great help especially when your software becomes large and you
need to refactor your code.
98
Exceptions
It's important to have a way to handle errors.Python gives us
exception handling.
try:
# some lines of code
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except <ERROR2>:
# handler <ERROR2>
To catch all exceptions you can use except withoutany error type:
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except:
# catch all other exceptions
99
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except <ERROR2>:
# handler <ERROR2>
else:
# no exceptions were raised, the code ran succe
try:
# some lines of code
except <ERROR1>:
# handler <ERROR1>
except <ERROR2>:
# handler <ERROR2>
else:
# no exceptions were raised, the code ran succe
finally:
# do something in any case
The specific error that's going to occur depends on the operation you're
performing.
result = 2 / θ
print(result)
100
Traceback (most recent call last):
File "main.py", line 1, in <module>
result = 2 / θ
ZeroDivisionError: division by zero
and the lines of code after the error will not beexecuted.
try:
result = 2 / θ
except ZeroDivisionError:
print('Cannot divide by zero!')
finally:
result = 1
print(result) # 1
You can raise exceptions in your own code, too, usingthe raise
statement:
try:
raise Exception('An error occurred!')
except Exception as error:
print(error)
101
class DogNotFoundException(Exception):
pass
try:
raise DogNotFoundException()
except DogNotFoundException:
print('Dog not found!')
102
The with statement
The with statement is very helpful to simplifyworking with
exception handling.
For example when working with files, each time weopen a file, we
must remember to close it.
Instead of writing:
filename = '/Users/flavio/test.txt'
try:
file = open(filename, 'r')
content = file.read()
print(content)
finally:
file.close()
filename = '/Users/flavio/test.txt'
with is not just helpful to work with files. The aboveexample is just
meant to introduce its capabilities.
103
Installing 3rd party packages
using pip
The Python standard library contains a huge numberof utilities that
simplify our Python development needs, but nothing can satisfy
everything.
Those modules are all collected in a single place, the Python Package
Index available at https://pypi.org, and they can be installed on your
system using pip .
There are more than 270.000 packages freely available, at the time of
writing.
For example you can install the requests package, apopular HTTP
library:
104
pip install requests
and once you do, it will be available for all your Pythonscripts,
because packages are installed globally.
105
List comprehensions
List comprehensions are a way to create lists in a veryconcise way.
numbers = [1, 2, 3, 4, 5]
numbers_power_2 = []
for n in numbers:
numbers_power_2.append(nCC2)
106
Polymorphism
Polymorphism generalizes a functionality so it can work on different
types. It's an important concept in object-oriented programming.
class Dog:
def eat():
print('Eating dog food')
class Cat:
def eat():
print('Eating cat food')
animal1 = Dog()
animal2 = Cat()
animal1.eat()
animal2.eat()
107
Operator Overloading
Operator overloading is an advanced technique wecan use to make
classes comparable and to make them work with Python operators.
class Dog:
# the Dog class
def init (self, name, age):
self.name = name
self.age = age
roger = Dog('Roger', 8)
syd = Dog('Syd', 7)
class Dog:
# the Dog class
def init (self, name, age):
self.name = name
self.age = age
def gt (self, other):
return True if self.age > other.age else Fa
Now if you try running print(roger > syd) you will getthe result True .
108
to
eq check
() for equality
ltto ()
check if an object should beconsidered lower
than another with the < operator
le () for lower or equal ( <= )
ge () for greater or equal ( >= )
ne () for not equal ( != )
109
Virtual Environments
It's common to have multiple Python applications running on your
system.
When applications require the same module, at some point you will
reach a tricky situation where an app needs a version of a module, and
another app a different version of that same module.
in the folder where you want to start the project, orwhere you
already have an existing project.
Then run
source .venv/bin/activate
110
➜ folder
to
(.venv) ➜ folder
111
Conclusion
Thanks a lot for reading this book.
112
113
114