
Explore how to build and use Python classes, initialize with __init__, and define properties like width and height. Implement area, perimeter, string representations, equality, and rich comparisons using Pythonic conventions.
Explore how Python uses reference counting to manage object lifetimes and track references. Inspect counts with get_ref_count and ctypes to see memory references in action.
Demonstrate function arguments and mutability in Python, highlighting how strings stay immutable and safe, while lists and mutable tuple elements may change via passed references.
Understand shared references and mutability in Python: how strings are immutable, how lists are mutable, and how passing references to functions can cause in place changes and side effects.
Explore how Python compares values and identity using the is and == operators, differentiate memory addresses, None handling, and how lists, numbers, and strings may share or differ in identity.
Explore how Python uses string interning to speed up identifier lookups and reduce memory, and learn when to force interning and when to use is versus == in string comparisons.
Explore peephole optimizations in Python, focusing on compile-time constant expressions that get pre-calculated, short sequences, and converting lists to tuples and sets to frozen sets for faster membership tests.
Explore truncation, floor, and ceiling in Python by using math.trunc (or trunk), the int constructor, floor, and ceil to convert floats to integers; understand differences with negative numbers.
Construct decimals with the decimal module's Decimal class using integers, strings, or tuples, avoiding floats for exact values. Context precision affects arithmetic, not construction, with global and local contexts.
Explore how the decimal constructor accepts integers, strings, tuples, or another decimal, yields zero with no input, and how global and local contexts affect arithmetic precision and float inaccuracies.
Learn complex numbers in Python using the built-in complex class, real and imaginary parts, literals with j, and polar-rectangular conversions with cmath, plus the is close method for Euler's identity.
Explore the boolean data type in Python, its inheritance from int, and how true and false behave as singleton bool objects alongside integer operations, truth values, and type conversions.
Discover how Python boolean operators work, including short-circuiting with or and and. Apply these concepts to set default values, handle truthy and falsy inputs, and use not to negate truth values.
Master positional and keyword arguments in a three-parameter function by mapping A, B, and C. See how default values make parameters optional and how keyword arguments must match parameter names.
Explore extended unpacking in Python, comparing slicing and start expressions, with practical examples for lists, strings, sets, and dictionaries. Learn nested unpacking and combining iterables to write clearer, flexible code.
Dive into Python keyword arguments, including positional versus named parameters, using star and star args, and enforcing mandatory and optional keyword arguments for robust function calls.
Document functions with docstrings and annotations to attach metadata, stored in __annotations__ and dunder doc, enabling external tools like Sphinx to generate documentation.
Explore lambda expressions as anonymous Python functions, created with the lambda keyword and a single expression body, assignable as function objects, passable as arguments, and comparable to def functions.
Explore function introspection by defining a Python function, inspecting its annotations, defaults, and docstring, and using inspect to examine code, signature, and parameter kinds.
Explore Python callables: what makes an object callable, how to test with callable(), and how functions, methods, classes, and instances can be invoked with the call operator.
Explore map, filter, zip, and list comprehensions in Python, handling generators, deferred calculations, and combining iterables with two lists, lambdas, and factorial examples.
Explore closures in Python, including free variables, non-local variables, and cells. Learn how closures capture outer scope, how memory cells work, and how nested closures behave.
Explore closures that implement counters and track function calls by capturing non-local state. Learn to pass functions, use inner closures, and store call counts in a dictionary.
Explore decorators in Python 3, using closures and higher-order functions to wrap functions, maintain state, and inspect metadata with wraps for proper naming and docs.
Learn how class instances become callable to decorate functions, implement a decorator factory, and compare closures and dunder call based decorators for function decoration.
Explore implementing a single dispatch generic function in Python using a decorator, a registry, and a type-based dispatch mechanism, including a register decorator and closures.
Explore Python tuples as immutable sequence records, distinguish them from lists, and learn how order matters and positions carry meaning. See how named tuples give names to positions for records.
Compare tuples with lists and strings as sequence types, and explore their container nature, immutability, and fixed length; learn how to use tuples for data records and unpacking data.
Explore using tuples as data structures in Python, including indexing, slicing, unpacking (extended with star), immutability nuances, and practical city tuples and function returns.
Explore named tuples, their docstrings, and how to set default values with prototype and dunder defaults. Learn to create 2d vectors with origin x and y defaults using underscore replace.
Explore modules, packages, and package namespaces in Python. Learn how Python loads modules and the various import variants, including caching and reloading safety.
Explore how Python packages and modules are created and imported, including dunder init files and nested packages. Learn how Python resolves paths and dot notation to access modules.
Preserve insertion order in Python 3.6 dictionaries when iterating keys, values, and items, making them comparable to ordered dicts. Note caveats about 3.6 versus 3.7 official status.
Python 3.6 preserves the order of keyword arguments, enabling a defaulted named tuple factory that defines fields and defaults, illustrated by a vector2d with zero origins.
Hello!
This is Part 1 of a series of courses intended to dive into the inner mechanics and more complicated aspects of Python 3.
This is not a beginner course!
If you've been coding Python for a week or a couple of months, you probably should keep writing Python for a bit longer before tackling this series.
On the other hand, if you've been studying or programming in Python for a while, and are now starting to ask yourself questions such as:
I wonder how this works?
is there another, more pythonic, way, of doing this?
what's a closure? is that the same as a lambda?
I know how to use a decorator someone else wrote, but how does it work? How do I write my own?
why do some boolean expressions not return a boolean value? How can I use that to my advantage?
how does the import mechanism in Python work, and why am I getting side effects?
and similar types of question...
then this course is for you.
To get the most out of this course, you should be prepared to pause the coding videos, and attempt to write code before I do! Sit back during the concept/theory videos, but lean in for the code videos!
Please make sure you review the pre-requisites for this course (below) - although I give a brief refresh of basic concepts at the beginning of the course, those are concepts you should already be very comfortable with as you being this course.
In this course series, I will give you a much more fundamental and deeper understanding of the Python language and the standard library.
Python is called a "batteries-included" language for good reason - there is a ton of functionality in base Python that remains to be explored and studied.
So this course is not about explaining my favorite 3rd party libraries - it's about Python, as a language, and the standard library.
In particular this course is based on the canonical CPython. You will also need Jupyter Notebooks to view the downloadable fully-annotated Python notebooks.
It's about helping you explore Python and answer questions you are asking yourself as you develop more and more with the language.
In Python 3: Deep Dive (Part 1) we will take a much closer look at:
Variables - in particular that they are just symbols pointing to objects in memory (references)
Namespaces and scopes
Python's numeric types
Python boolean type - there's more to a simple or statement than you might think!
Run-time vs compile-time and how that affects function defaults, decorators, importing modules, etc
Functions in general (including lambdas)
Functional programming techniques (such as map, reduce, filter, zip, etc)
Closures
Decorators
Imports, modules and packages
Tuples as data structures
Named tuples
Course Prerequisites
This is an intermediate to advanced Python course.
To have the full benefit of this course you should be comfortable with the basic Python language including:
variables and simple types such as str , bool , int and float types
for and while loops
if...else... statements
using simple lists , tuples , dictionaries and sets
defining functions (using the def statement)
writing simple classes using the class keyword and the __init__ method, writing instance methods, creating basic properties using @property decorators
importing modules from the standard library (e.g. import math)
You should also:
have Python 3.6 (or higher) installed on your system
be able to write and run Python programs using either:
the command line, or
a favorite IDE (such as PyCharm),
have Jupyter Notebooks installed (which I use throughout this course so as to provide you fully annotated Python code samples)