Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Subclassing Immutable Built-in Types

If you’re interested in converting units, then you can check out Pint.

00:00 Subclassing Immutable Built-in Types. Let’s start with a use case of .__new__() that consists of subclassing an immutable built-in type. As an example, let’s say you need to write a Distance class as a subclass of Python’s float type.

00:17 Your class will have an additional attribute to store the unit that’s used to measure the distance. Here’s a first approach to this problem, using the .__init__() method.

00:45 When you subclass an immutable built-in data type, you get an error. Part of the problem is that the value is set during creation, and it’s too late to change it during initialization. Additionally, float.__new__() is called under the hood, and it doesn’t deal with extra arguments in the same way as object.__new(). This is what raises the error seen in this example.

01:08 To work around this issue, you can initialize the object at creation time with .__new__() instead of overriding .__init__(). Here’s how this is done in practice.

01:24 Here, .__new__() runs the three steps that you learned in the previous section. First, the method creates a new of the current class, cls, by calling super().__new__().

01:35 This time, the call rolls back to float.__new__(), which creates a new instance and initializes it using value as an argument.

01:43 Then the method customizes the new instance by adding a .unit attribute to it. Finally, the new instance gets returned.

01:53 Now your Distance class works as expected, allowing you to use an instance attribute for storing the unit in which you’re measuring the distance.

02:01 Unlike the floating-point value stored in a given instance of Distance, the .unit attribute is mutable, so you can change its value any time you like.

02:10 Finally, note how a call to the dir() function reveals that your class inherits features and methods from float.

02:22 Note that the Distance class in this example doesn’t provide a proper unit conversion mechanism. This means that something like Distance(10, "km") + Distance(20, "miles") won’t attempt at converting units before adding the values.

02:39 If you’re interested in converting units, then check out this project on PyPI. Having seen how to subclass a built-in, in the next section of the course, you’ll see how a class can return an instance of a different class.

Become a Member to join the conversation.