On Tue, 20 Dec 2022 at 11:16, Steven D'Aprano <st...@pearwood.info> wrote:
> Speaking of dicts, the dict.fromkeys method cooperates with subclasses.
> That proves that it can be done from a builtin. True, it is a
> classmethod rather than an instance method, but any instance method can
> find out its own class by calling `type()` (or the internal, C
> equivalent) on `self`. Just as we can do from Python.
>

What you really mean here is that fromkeys cooperates with subclasses
*that do not change the signature of __init__*. Otherwise, it won't
work.

The reason this is much easier with a classmethod alternate
constructor is that, if you don't want that behaviour, just don't do
that.

>>> class NumDict(dict):
...     def __init__(self, max, /):
...             for i in range(max): self[i] = i
...
>>> NumDict(10)
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
>>> NumDict(5)
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4}
>>> NumDict.fromkeys("abc")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: NumDict.__init__() missing 1 required positional argument: 'max'

So? Just don't use NumDict.fromkeys(), it doesn't make sense for a
NumDict. And that's fine. But if something else didn't work, it would
cause major problems. Which is why instance methods return plain
dictionaries:

>>> type(NumDict(5) | NumDict(3))
<class 'dict'>

How is the vanilla dictionary supposed to know how to construct a
NumDict correctly? Come to think of it, how is dict supposed to know
how to construct a defaultdict? Oh, it doesn't really.

>>> d = defaultdict.fromkeys("asdf", 42)
>>> d["a"]
42
>>> d["b"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'b'
>>> d
defaultdict(None, {'a': 42, 's': 42, 'd': 42, 'f': 42})

All it does is construct a vanilla dictionary, because that's all it
knows how to do.

If the rule is "all operations return an object of the subclass
automatically", then the corollary is "all subclasses must retain the
signature of the superclass".

ChrisA
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/45GP3NBIUC3B6MQINMKMZLW4JNOCMOFL/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to