Introduction to Python
Python is a high level, dynamically typed, interpreted language whose whole design goal is that a program should be as easy to read as it was to write.
- Basics
- Data Types
- Operators
- Strings
- Control Flow
- Lists
- Tuples
- Sets
- Dictionaries
- Comprehensions
- Functions
- Advanced Functions
- Recursion
- Exception Handling
- File Handling
- Modules
- Standard Library
- OOP
- Advanced OOP
- Iterators and Generators
- Decorators
- Context Managers
- Descriptors and Dataclasses
- Python Internals
- Concurrency
- Regular Expressions
- Serialization
- Command Line Python
- Testing and Debugging
- Type Hints
- Performance
- Python Security
- DSA with Python
What Python is
Python is a general purpose programming language. It is high level, meaning it hides memory addresses and machine registers from you; dynamically typed, meaning a variable is not tied to one type; and interpreted in the sense that you hand it source code and it starts running, with no separate build step that you have to manage.
The single idea that explains almost every design decision in Python is this: code is read far more often than it is written. Wherever the language had a choice between a clever short form and an obvious readable form, it chose the readable one. That is why blocks are marked by indentation instead of braces, why keywords are ordinary English words such as and, or, not and in, and why the standard library prefers a plain function name over a symbol.
Why Python is used so widely
- Small surface area. A beginner can write a useful program after learning perhaps fifteen keywords. The language does not require you to understand classes, types or memory before printing a line of text.
- Batteries included. The standard library ships with modules for maths, dates, files, paths, JSON, regular expressions, testing, logging, command line parsing and much more. These notes stay inside that boundary throughout.
- It glues things together. Python is comfortable calling out to code written in other languages, which is why it became the control layer for so many systems.
- One obvious way. The community deliberately converges on a single idiom for common tasks, so code written by two different people tends to look the same.
Where it fits and where it does not
| Good fit | Poor fit |
|---|---|
| Automation and scripting | Hard real time control systems |
| Data processing and reporting | Code that must fit in a few kilobytes of memory |
| Back end services and APIs | Tight numeric loops written in pure Python |
| Tooling, build systems, glue code | Situations demanding compile time type guarantees |
| Teaching programming | Shipping a closed source binary |
The weaknesses are honest consequences of the strengths. Dynamic typing means some mistakes surface only when a line actually runs. Interpretation means a pure Python loop is much slower than the same loop in a compiled language. Both are usually acceptable, and both have practical answers covered later in this path.
Characteristics worth knowing by name
- Dynamically typed - a name has no declared type. The object it refers to has a type, and that never changes.
- Strongly typed - Python does not quietly convert unrelated types for you.
2 + "3"is an error, not5and not"23". - Everything is an object - numbers, strings, functions, classes and modules are all objects with attributes.
- Automatic memory management - you never free anything by hand. Objects disappear when nothing refers to them.
- Multi paradigm - procedural, object oriented and functional styles are all supported, and most real programs mix them.
Python 2 and Python 3
Python 2 reached the end of its life in 2020 and receives no fixes of any kind. Every line in these notes is Python 3. The distinction still matters because a great deal of very old material online is written for Python 2, and the two are not compatible.
| Python 2 | Python 3 |
|---|---|
print "hi" is a statement | print("hi") is a function call |
5 / 2 gives 2 | 5 / 2 gives 2.5 |
| Text is bytes by default | Text is Unicode by default |
range() builds a list | range() is lazy |
If you find a code sample with print used without brackets, you are reading Python 2 material. Close it and find something current.Versions inside Python 3
A feature release of Python arrives roughly once a year, and each one is supported for about five years. Features that these notes rely on are marked with the version that introduced them wherever the version matters, for example f-strings in 3.6, dataclasses in 3.7, the walrus operator in 3.8, dictionary merge with | in 3.9 and structural pattern matching in 3.10.
A first look at the language
def describe(temperature):
if temperature > 35:
return "hot"
elif temperature > 20:
return "pleasant"
return "cold"
for reading in [18, 24, 41]:
print(reading, describe(reading))18 cold
24 pleasant
41 hotThere is no type declaration, no semicolon, no braces and no separate compile command. The indentation is not decoration: it is the only thing that tells Python which lines belong to the function and which belong to the loop.
Common misconceptions
- Python is only a scripting language. It is used for long running production services just as much as for short scripts. The word "scripting" describes a use case, not a limit.
- Dynamic typing means no types. Python has types and enforces them strictly. What is dynamic is the binding between a name and an object, not the type of the object.
- Python is slow, therefore unusable. The interpreter is slower per operation than compiled code. Most programs spend their time waiting on files, networks or databases, where that difference does not appear.
- Indentation is a stylistic preference. It is syntax. Getting it wrong is a hard error, not an untidy result.
Practice
- Name three properties of Python that follow directly from the goal of readability.
- Explain the difference between dynamically typed and weakly typed, and say which one Python is.
- You find a tutorial containing
print "Total". What does that tell you, and what should you do about it? - Give one task Python suits well and one it suits badly, and justify each in a single sentence.
Conclusion
Python trades a little raw speed for a great deal of clarity, and does so deliberately. Hold on to two facts as you continue: names refer to objects rather than containing them, and indentation is part of the grammar. Almost everything else in this path builds on those two.