[Python-Dev] subclassing builtin data structures (original) (raw)
Neil Girdhar mistersheik at gmail.com
Sat Feb 14 00:03:35 CET 2015
- Previous message: [Python-Dev] subclassing builtin data structures
- Next message: [Python-Dev] subclassing builtin data structures
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I personally don't think this is a big enough issue to warrant any changes, but I think Serhiy's solution would be the ideal best with one additional parameter: the caller's type. Something like
def make_me(self, cls, *args, **kwargs)
and the idea is that any time you want to construct a type, instead of
self.class(assumed arguments…)
where you are not sure that the derived class' constructor knows the right argument types, you do
def SomeCls: def some_method(self, ...): return self.make_me(SomeCls, assumed arguments…)
Now the derived class knows who is asking for a copy. In the case of defaultdict, for example, he can implement make_me as follows:
def make_me(self, cls, *args, **kwargs): if cls is dict: return default_dict(self.default_factory, *args, **kwargs) return default_dict(*args, **kwargs)
essentially the caller is identifying himself so that the receiver knows how to interpret the arguments.
Best,
Neil
On Fri, Feb 13, 2015 at 5:55 PM, Alexander Belopolsky < alexander.belopolsky at gmail.com> wrote:
On Fri, Feb 13, 2015 at 4:44 PM, Neil Girdhar <mistersheik at gmail.com> wrote:
Interesting: http://stackoverflow.com/questions/5490824/should-constructors-comply-with-the-liskov-substitution-principle
Let me humbly conjecture that the people who wrote the top answers have background in less capable languages than Python. Not every language allows you to call self.class(). In the languages that don't you can get away with incompatible constructor signatures. However, let me try to focus the discussion on a specific issue before we go deep into OOP theory. With python's standard datetime.date we have: >>> from datetime import * >>> class Date(date): ... pass ... >>> Date.today() Date(2015, 2, 13) >>> Date.fromordinal(1) Date(1, 1, 1) Both .today() and .fromordinal(1) will break in a subclass that redefines new as follows: >>> class Date2(date): ... def new(cls, ymd): ... return date.new(cls, *ymd) ... >>> Date2.today() Traceback (most recent call last): File "", line 1, in TypeError: new() takes 2 positional arguments but 4 were given >>> Date2.fromordinal(1) Traceback (most recent call last): File "", line 1, in TypeError: new() takes 2 positional arguments but 4 were given Why is this acceptable, but we have to sacrifice the convenience of having Date + timedelta return Date to make it work with Date2: >>> Date2((1,1,1)) + timedelta(1) datetime.date(1, 1, 2) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20150213/1b0427d5/attachment.html>
- Previous message: [Python-Dev] subclassing builtin data structures
- Next message: [Python-Dev] subclassing builtin data structures
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]