mirror of
https://github.com/python/cpython.git
synced 2025-10-03 13:45:29 +00:00
[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:
parent
c579f0ba62
commit
ac87b07a10
1 changed files with 48 additions and 0 deletions
|
@ -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
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue