Advanced Python: the depths of the language
By understanding advanced features such as descriptors, metaclasses, context managers and the import system, you see how frameworks work and write your own tools.
Level 401 · 17 lessons · 24 practice labs
Lessons
The object model
- Everything is an object: type, identity and value
- Attribute lookup order and __getattr__
- Descriptors: how property works
- __slots__ and memory
- Multiple inheritance and the MRO
- Short task: validated fields with a descriptor
Class creation
- Class decorators
- Automatic registration with __init_subclass__
- Metaclasses: when you really need one
- Parameterised decorators and functools.wraps
- Short task: plugin classes that register themselves
Resources and modules
- ExitStack and nested resources
- The import system: finders and loaders
- Dynamic loading with importlib and its risks
- Structural pattern matching: class and mapping patterns
- Short task: a small configuration language using context managers
Capstone
- Capstone: a small ORM built with descriptors and a metaclass
Practice labs
- Answering a missing setting with __getattr__: Write a __getattr__ that looks up undefined attributes of a settings object in a defaults dictionary and raises a clear AttributeError otherwise.
- Finding a method shadowed by an instance attribute: In an order class broken because an instance attribute shadows a method of the same name, trace the lookup order to find the bug and pass the tests.
- A proxy object that records attribute access: Write a proxy class that records every read and write on the wrapped object, forwards special methods correctly and never recurses infinitely.
- Writing a positive-number descriptor: Write a descriptor that checks an assigned value is a positive number and stores it per instance, then use it for two separate fields.
- Measuring the memory saved by __slots__: Add __slots__ to a class holding hundreds of thousands of sensor readings, measure memory before and after with tracemalloc and repair the weak reference that breaks.
- Repairing a descriptor that leaks across instances: Fix a descriptor that shows the same price on every instance because it stores the value on itself, using __set_name__ to store per instance.
- Adding __repr__ with a class decorator: Write a class decorator that adds an automatic __repr__ built from field names and try it on three different classes.
- Registering exporters automatically: Use __init_subclass__ to register every subclass under its format name, reject a duplicate name and return the right class by name.
- Simplifying an unnecessary metaclass: Replace a metaclass written only for field checks with __init_subclass__ and __set_name__ so existing tests still pass and the multiple-inheritance conflict disappears.
- Restoring the name lost in a decorator: Add functools.wraps to a timing decorator that swallows the name and docstring of decorated functions and show the help output is fixed.
- A parameterised retry decorator: Write a decorator that takes the number of attempts and the exception types to catch and raises the last error with chaining.
- Fixing the order of mixin classes: Inspect the MRO of mixins that break the super() chain, add the missing super calls and prove by test that every step runs exactly once.
- Managing many files with ExitStack: Open a number of files known only at run time with ExitStack and show by test that the earlier ones are closed if one fails to open.
- Dispatching event dictionaries with match: Dispatch event dictionaries arriving in different shapes with mapping and class patterns and put unrecognised shapes in a separate list.
- Restricting dynamic plugin loading: Harden a plugin loader that imports any module name the user supplies so it checks an allowed package prefix and the expected interface.
- A decorator that works with and without parentheses: Write a timing decorator that works both as @timed and as @timed(threshold=...), on functions and on methods, preserving the wrapped function's signature and docstring.
- Reading the method resolution order: Inspect which method gets called in a small diamond-shaped class tree using __mro__ and fix the order of the base classes to give the order the test expects.
- Cooperative initialisers with super(): Fix classes that skip a base class initialiser under multiple inheritance by using cooperative super() calls that pass keyword arguments along the chain.
- A context manager that restores the working directory: Write a context manager with contextlib.contextmanager that temporarily changes the working directory and returns to the old one even when the block raises.
- A context manager class that rolls back on error: Add __enter__ and __exit__ to a settings update class so changes are rolled back if the block raises, only the designated exception type is suppressed and others propagate.
- Splitting command words with match: Route a space-separated command line to add, remove and list actions with match and sequence patterns, returning a clear message for an unknown command.
- Evaluating an expression tree with class patterns and guards: Evaluate an expression tree made of dataclasses using class patterns, nested patterns and guarded cases, with division by zero and unknown nodes raising separate errors.
- Loading a module by name: Load the formatter module named in a settings file with importlib.import_module and call its function, giving a clear error when the module does not exist.
- Loading an optional dependency on demand: Load a heavy library used by only one subcommand on first use; when it is not installed the other commands keep working and an install hint is shown.
About this course
By understanding advanced features such as descriptors, metaclasses, context managers and the import system, you see how frameworks work and write your own tools.
What you will learn
- The object model
- Class creation
- Resources and modules
- Capstone
Prerequisites
You should have practised the topics of the same path up to level 301.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 401; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.