In the previous lesson, I showed you exception groups, the new
except* syntax, and the
TaskGroup() addition to
In this lesson, I’ll be describing the additions to the
Self type is used in a similar fashion to
self in a class. It indicates the use of the object being used. This is useful in factory methods, those methods on a class that return an instance of the object.
In this example, the
.from_json() method returns an instance of the
Person class. It’s a factory for the person based on a JSON string.
Self type indicates that the method is returning an instance of the class that the method belongs to.
TypeVar type is used to indicate the use of a single type, but what if you need more than one of those? Enter the new
00:58 This declares an arbitrary-length number of types. Generics like this are called variadic, meaning they are of variable length.
01:07 Consider this code that takes the first item in a tuple and moves it to the last item in a tuple. The function takes a tuple that starts with one thing, then is followed by a variable number of things.
01:21 The function returns a new tuple comprised of the variable-length things, and then the first thing.
Many libraries use dataclass-like semantics—for example, Django
ORM objects, Django REST framework serializers, Pydantic models, and Ninja schemas.
01:41 Each of these declares a grouping of fields which are very dataclass-like. If dataclasses existed sooner, many of these libraries may have used them. To help the typing systems understand the intent of these kinds of objects, the dataclass transform introduced in Python 3.11 indicates that dataclass-like objects are, well, dataclass-like.
02:02 Like the dataclass transform comes as a decorator, and you can use it with functions, classes, or metaclasses depending on how you are creating the resulting dataclass-like object. Consider the following example.
If I have a common
ModelBase class that all my serializable objects inherit from, I can decorate that with the dataclass transform. I then create a
CustomerModel class that inherits from that
02:29 My customer class has two fields, an ID and a name.
The initializer for my customer model would take the ID and name as parameters in a similar fashion to a dataclass, making it dataclass-like. Because I used the transform on the base class, the
CustomerModel class gets marked as dataclass-like. This is sort of like duck typing, indicating membership based on availability of a feature. In this case, that feature is how the initializer works.
02:59 Mypy or your IDE could now indicate if some of the attributes are missing from the initializer, as they would understand that you intended dataclass-like semantics.
Two more smaller additions for you. The first is
LiteralString. This type indicates how a string was constructed. A literal is anything that is directly declared as a string.
03:25 A string that is constructed with a concatenation is not a literal. This kind of typing allows you to declare a function that only accepts literal types, which can help you avoid things like SQL injection vulnerabilities.
TypedDict type has two new subtypes that can be used with it:
NotRequired. These adapters allow you to declare which keys in the
TypedDict class are mandatory or optional. With every release, there’s always some smaller items. Next up, a bunch of unrelated stuff and things.
Become a Member to join the conversation.