
Explore objects and classes in Python, cover instantiation and initialization, distinguish data attributes from methods, and learn binding with instance, class, and static methods, plus properties.
Define a class and mutate its attributes with dot notation and get/set attribute, such as language and version, and examine how the object's state appears in its mapping proxy.
Explore data attributes in Python by creating bank account instances, examining class attributes like APR and account type, and learning how instance attributes hide class attributes.
Explore how function attributes become bound methods in Python, with the instance injected as the first argument, and compare instance methods with regular functions using say hello and language examples.
Learn how Python creates and initializes class instances using the dunder init method to set initial attributes, binding to the object and handling init arguments.
Learn how to create attributes and bound methods at run time in Python by monkey-patching instances, using function and method types, and customizing instance behavior.
Learn how read-only and computed properties work in Python, using backing variables and the @property decorator to create lazy, cached attributes like circle area.
Learn how read-only and computed properties work in Python, using circle area caching and radius updates to illustrate cache invalidation, lazy loading, and property decorators.
Delete properties from instances, not the class; removing the underscore color from the instance dictionary uses the delete keyword or the delattr function.
Delve into deleting properties by implementing a deleter alongside getter and setter, using both old-style and decorator syntax, and observe backing variables and the instance dictionary.
Examine how the property class provides a convenient way to define instance properties and class properties, its reuse limitations, and the potential for data descriptors and metaprogramming.
Explore how instance methods, class methods, and static methods behave in Python classes, with timer examples, time zone handling, and class-level attributes.
Design a bank account system with a time zone class and an account class to manage deposits, withdrawals, non negative balances, and a monthly interest; generate confirmations with UTC timestamps.
Build a time zone class with name and offset, represented by a timedelta. Validate inputs, expose read-only properties, and define equality for reliable comparisons.
Implement account number as read-only, and first name and last name with private attributes and properties, using a static name validator and setattr-based setter to ensure non-empty values.
Add a preferred time zone to the account class as an optional argument defaulting to UTC, with a time zone property and setter that enforces a valid time zone object.
Explore implementing a shared interest rate for bank accounts using a private class variable and class methods for get and set, with real-number and non-negative validation.
Explore the __str__ and __repr__ dunder methods and how Python uses them to display and recreate objects, with fallback behavior when __str__ is absent.
Explore implementing arithmetic operators for a vector class using dunder methods, including addition, subtraction, scalar multiplication, dot product, and in-place variants.
Explore how Python determines truth values for objects using __bool__ and __len__, with examples of custom classes, including lists, points, and default truthiness.
Make objects callable by implementing the dunder call method, turning class instances into function-like objects that can maintain state. Enable decorator classes and richer function-like behavior.
Explore the __del__ method, a class finalizer invoked by the garbage collector before object destruction. Learn unpredictability, risks with references and exceptions, and why context managers are preferred for cleanup.
Learn how Python's format function and the __format__ method format values with a format spec, including numbers and dates, with custom classes delegating to representation when no spec is given.
Explore Python's format function and the __format__ method, learn to format floats and date times with custom specifiers, and understand delegation to existing formatters for clean, reusable code.
Explore modular arithmetic by implementing a mod class in Python that handles residues, congruence, hashability, and arithmetic operations with same modulus or integers.
Explore overriding in Python by redefining parent callables in a subclass, observe how method binding to an instance affects calls, and see how inherited and object methods are resolved.
Learn to delegate to parent methods with super in Python, ensuring correct binding, avoiding recursion, and proper initialization through the hierarchy.
Discover how slots in Python store only predefined attributes, avoiding per-instance dictionaries and delivering substantial memory savings and faster attribute access for large numbers of objects, while restricting new attributes.
Explore how slots constrain instance attributes, define read-only properties for longitude and latitude, and distinguish class attributes from instance dictionaries while enforcing keyword-only arguments.
Explore slots in single inheritance and how a subclass inherits slots from the base class. Observe how the instance dictionary coexists with slots, and how to mix them for flexibility.
Examine single inheritance and __slots__ in Python to see how __slots__ affects the instance dictionary, then extend slots in subclasses to control storage and add fields.
Develop a Python 3 oop inventory model with a base resource class and cpu, hdd, ssd subclasses, including validation and allocation methods like claim, free_up, and purchased.
Create a validators module with a validate integer function that enforces optional min and max bounds, supports custom error messages, and develops unit tests with Pi test.
Define a cpu class that inherits from resource, implements init with cores, socket, and power watts, validates inputs, exposes read‑only properties, and includes pytest tests for inventory validation.
Explore the storage class inheriting from resource, with capacity in gigabytes and a read only capacity property. Write and run test_storage unit tests for creation, invalid values, and representation.
Explore how Python descriptors implement getters and setters, including class versus instance access, and why descriptor state must be stored per instance to avoid shared values.
Explore how the __set_name__ method recovers descriptor property names at class creation, enabling robust data descriptors, instance storage, and validation messages for properties like first name and last name.
Explore properties and data descriptors in Python by implementing a property object with get, set, and delete methods, and see how dunder get and dunder set control attribute access.
Explore Python properties and descriptors, implementing getters and setters with decorators, adding validation, and building a MakeProperty data descriptor to mirror built-in behavior.
Create reusable data descriptors to enforce types like int, float, and list in class attributes, using a generic valid type that relies on numbers.real for real numbers.
Apply data descriptors to enforce that polygon vertices are a sequence of Point2D with nonnegative integer coordinates, using an INT descriptor and inheritance to define triangle and rectangle.
Explore how functions become methods in Python through descriptors and the non-data descriptor protocol. See how the __get__ method binds functions to instances, producing bound methods and method objects.
Create two data descriptors, integer field and cow field, with optional min and max constraints. Implement a base validator for inheritance and add unit tests to verify validation logic.
Explore how aliases work in Python enums, where multiple names share a master member, and how lookups, containment, iteration reveal the master and how the unique decorator prevents aliases.
Explore how Python's enum auto assigns values to members via a static generate next value method, defaulting to sequential integers starting at one and noting aliases and last values.
Learn how Python enums compute automatic values with auto, override generate next value, and manage aliases, duplicates, and custom value strategies in enum members.
This Python3: Deep Dive Part 4 course takes a closer look at object oriented programming (OOP) in Python.
MAIN COURSE TOPICS
what are classes and instances
class data and function attributes
properties
instance, class and static methods
polymorphism and the role special functions play in this
single inheritance
slots
the descriptor protocol and its relationship to properties and functions
enumerations
exceptions
metaprogramming (including metaclasses)
COURSE PREREQUISITES
Please note this is NOT a beginner level course. You must have a strong working knowledge of functional Python programming as well as some practical experience developing Python applications in order to fully benefit from this course.
In-depth functional Python programming
functions, closures, scopes, decorators (using and writing them)
zip, sorted, any, all, and the itertools module in general
sequences, iterables, iterators and generators (what they are and how to implement the corresponding protocols)
generators, yield, and context managers
mapping types, hashing and relation to object equality
some prior knowledge of basic OOP concepts
know how to work with Python virtual environments and pip install
available Jupyter Notebook (freely available) to follow along with the course notebooks
how to use git
[Please note that this is not a cookbook style course - I don't show you how to solve specific problems, but rather a broad and in-depth look at how OOP works in the context of Python, that will allow you to apply these concepts and techniques to your own problems.]