<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Feb 12, 2015 at 7:55 PM, Guido van Rossum <span dir="ltr"><<a href="mailto:guido@python.org" target="_blank">guido@python.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">the problem is that the base class (e.g. int) doesn't know how to construct an instance of the subclass -- there is no reason (in general) why the signature of a subclass constructor should match the base class constructor, and it often doesn't.</blockquote></div><br>I hear this explanation every time we have a discussion about subclassing of datetime types and I don't really buy this.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Consider this simple subclass:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> from datetime import date</div><div class="gmail_extra">>>> class Date(date):</div><div class="gmail_extra">...     pass</div><div class="gmail_extra">...</div><div class="gmail_extra"><br></div><div class="gmail_extra">What do you think Date.today() should return?  Since I did not override todat() in my Date class, it has to be datetime.date instance, right?</div><div class="gmail_extra"><br></div><div class="gmail_extra">However:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> Date.today().__class__</div><div class="gmail_extra"><class '__main__.Date'></div><div class="gmail_extra"><br></div><div class="gmail_extra">Wait, Date "doesn't know how to construct an instance of the subclass .."</div><div class="gmail_extra"><br></div><div class="gmail_extra">Indeed, if I change the constructor signature, Date.today() won't work:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> class Date(date):</div><div class="gmail_extra">...     def __init__(self, extra):</div><div class="gmail_extra">...         pass</div><div class="gmail_extra">...</div><div class="gmail_extra">>>> Date.today()</div><div class="gmail_extra">Traceback (most recent call last):</div><div class="gmail_extra">  File "<stdin>", line 1, in <module></div><div class="gmail_extra">TypeError: __init__() takes exactly 2 arguments (4 given)</div><div class="gmail_extra"><br></div><div class="gmail_extra">In my view, a constructor is no different from any other method.  If the designers of the subclass decided to change the signature in an incompatible way, they should either override all methods that create new objects or live with tracebacks.</div><div class="gmail_extra"><br></div><div class="gmail_extra">On the other hand, if all I want in my Date class is a better __format__ method, I am forced to override all operators or have my objects silently degrade in situations like this:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> d = Date.today()</div><div class="gmail_extra"><div class="gmail_extra">>>> d.__class__</div><div class="gmail_extra"><class '__main__.Date'></div></div><div class="gmail_extra">>>> d += timedelta(1)</div><div class="gmail_extra">>>> d.__class__</div><div class="gmail_extra"><type 'datetime.date'></div><div class="gmail_extra"><br></div><div class="gmail_extra">Having binary operations return subclass instances is not without precedent.  For example, in numpy, </div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> from numpy import ndarray</div><div class="gmail_extra">>>> class Array(ndarray):</div><div class="gmail_extra">...     pass</div><div class="gmail_extra">...</div><div class="gmail_extra"><div class="gmail_extra">>>> a = Array(1)</div><div class="gmail_extra">>>> a[0] = 42</div><div class="gmail_extra">>>> a</div><div class="gmail_extra">Array([ 42.])</div><div class="gmail_extra">>>> a + a</div><div class="gmail_extra">Array([ 84.])</div></div><div class="gmail_extra"><div class="gmail_extra"><br></div><div class="gmail_extra">I believe numpy had this behavior since types became subclassable in Python, so this design is definitely not a "no-go."</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div></div></div></div></div></div></div></div>