[3.9] bpo-4442: Document use of __new__ for subclasses of immutable types (GH-27866) (GH-27900)

(cherry picked from commit eec340ea3a)

Co-authored-by: Raymond Hettinger <rhettinger@users.noreply.github.com>
This commit is contained in:
Łukasz Langa 2021-08-22 22:14:25 +02:00 committed by GitHub
parent c579f0ba62
commit ac87b07a10
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1828,6 +1828,54 @@ For example, here is the implementation of
return False return False
How can a subclass control what data is stored in an immutable instance?
------------------------------------------------------------------------
When subclassing an immutable type, override the :meth:`__new__` method
instead of the :meth:`__init__` method. The latter only runs *after* an
instance is created, which is too late to alter data in an immutable
instance.
All of these immutable classes have a different signature than their
parent class:
.. testcode::
from datetime import date
class FirstOfMonthDate(date):
"Always choose the first day of the month"
def __new__(cls, year, month, day):
return super().__new__(cls, year, month, 1)
class NamedInt(int):
"Allow text names for some numbers"
xlat = {'zero': 0, 'one': 1, 'ten': 10}
def __new__(cls, value):
value = cls.xlat.get(value, value)
return super().__new__(cls, value)
class TitleStr(str):
"Convert str to name suitable for a URL path"
def __new__(cls, s):
s = s.lower().replace(' ', '-')
s = ''.join([c for c in s if c.isalnum() or c == '-'])
return super().__new__(cls, s)
The classes can be used like this:
.. doctest::
>>> FirstOfMonthDate(2012, 2, 14)
FirstOfMonthDate(2012, 2, 1)
>>> NamedInt('ten')
10
>>> NamedInt(20)
20
>>> TitleStr('Blog: Why Python Rocks')
'blog-why-python-rocks'
Modules Modules
======= =======