mirror of
https://github.com/python/cpython.git
synced 2025-11-13 15:40:05 +00:00
bpo-4442: Document use of __new__ for subclasses of immutable types (GH-27866)
This commit is contained in:
parent
dabb6e8ddd
commit
eec340ea3a
1 changed files with 49 additions and 0 deletions
|
|
@ -1826,6 +1826,55 @@ For example, here is the implementation of
|
||||||
return True
|
return True
|
||||||
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'
|
||||||
|
|
||||||
|
|
||||||
How do I cache method calls?
|
How do I cache method calls?
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue