From 3edc4a41f7f555b59b42af0192e8af07219149e7 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 20 Aug 2021 19:22:13 -0500 Subject: [PATCH 1/4] bpo-4442: Document use of __new__ for subclasses of immutable types --- Doc/faq/programming.rst | 49 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index af4b489fc8a483..90df58a293435e 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1826,6 +1826,55 @@ For example, here is the implementation of return True 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 when it is too late to store data in an +immutable instance. + +For example, all of these classes modify the inherited contructor. + +.. 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' + + How do I cache method calls? ---------------------------- From 258e032e75ac6a0c1ce5cef2335879d95db5285f Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 20 Aug 2021 19:38:37 -0500 Subject: [PATCH 2/4] More wordsmithing --- Doc/faq/programming.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 90df58a293435e..6bde474dbb0c03 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1831,11 +1831,12 @@ 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 when it is too late to store data in an -immutable instance. +instead of the :meth:`__init__` method. The latter only runs *after* an +instance is created which is too late to store data in an immutable +instance. -For example, all of these classes modify the inherited contructor. +For example, all of these immutable classes have a different signature +than the type they inherited from: .. testcode:: @@ -1846,7 +1847,6 @@ For example, all of these classes modify the inherited contructor. 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} From 33d0dc4debeb4a9c767227eae27b1640f5ddb3e5 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 20 Aug 2021 19:46:01 -0500 Subject: [PATCH 3/4] More wordsmithing --- Doc/faq/programming.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index 6bde474dbb0c03..ace767606c8b43 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1835,8 +1835,8 @@ instead of the :meth:`__init__` method. The latter only runs *after* an instance is created which is too late to store data in an immutable instance. -For example, all of these immutable classes have a different signature -than the type they inherited from: +All of these immutable classes have a different signature than their +parent class: .. testcode:: From 13ca777eb6d2c0e6972792259c71544f661310a7 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Fri, 20 Aug 2021 19:48:39 -0500 Subject: [PATCH 4/4] More wordsmithing --- Doc/faq/programming.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index ace767606c8b43..ef80808a1a4d5e 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -1832,7 +1832,7 @@ 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 store data in an immutable +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