<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 13, 2015 at 4:44 PM, Neil Girdhar <span dir="ltr"><<a href="mailto:mistersheik@gmail.com" target="_blank">mistersheik@gmail.com</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"><div dir="ltr">Interesting: <a href="http://stackoverflow.com/questions/5490824/should-constructors-comply-with-the-liskov-substitution-principle" target="_blank">http://stackoverflow.com/questions/5490824/should-constructors-comply-with-the-liskov-substitution-principle</a></div></blockquote></div><br>Let me humbly conjecture that the people who wrote the top answers have background in less capable languages than Python.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Not every language allows you to call self.__class__().  In the languages that don't you can get away with incompatible constructor signatures.</div><div class="gmail_extra"><br></div><div class="gmail_extra">However, let me try to focus the discussion on a specific issue before we go deep into OOP theory.</div><div class="gmail_extra"><br></div><div class="gmail_extra">With python's standard datetime.date we have:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> from datetime import *</div><div class="gmail_extra">>>> class Date(date):</div><div class="gmail_extra">...     pass</div><div class="gmail_extra">...</div><div class="gmail_extra">>>> Date.today()</div><div class="gmail_extra">Date(2015, 2, 13)</div><div class="gmail_extra"><div class="gmail_extra">>>> Date.fromordinal(1)</div><div class="gmail_extra">Date(1, 1, 1)</div><div class="gmail_extra"><br></div><div class="gmail_extra">Both .today() and .fromordinal(1) will break in a subclass that redefines __new__ as follows:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra"><div class="gmail_extra">>>> class Date2(date):</div><div class="gmail_extra">...     def __new__(cls, ymd):</div><div class="gmail_extra">...         return date.__new__(cls, *ymd)</div><div class="gmail_extra">...</div><div class="gmail_extra"><div class="gmail_extra">>>> Date2.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: __new__() takes 2 positional arguments but 4 were given</div><div class="gmail_extra">>>> Date2.fromordinal(1)</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: __new__() takes 2 positional arguments but 4 were given</div></div></div><div class="gmail_extra"><br></div><div class="gmail_extra">Why is this acceptable, but we have to sacrifice the convenience of having Date + timedelta</div><div class="gmail_extra">return Date to make it work  with Date2:</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div class="gmail_extra">>>> Date2((1,1,1)) + timedelta(1)</div><div class="gmail_extra">datetime.date(1, 1, 2)</div></div></div></div><div class="gmail_extra"><br></div></div><div class="gmail_extra"><br></div></div>