On Mon, 16 Aug 2010 05:01:58 pm Knacktus wrote: > Hello everyone, > > I've got a question about class design. I want to model classes like > these (examples): > > ##################################################################### > class BaseItem(object): > def __init__(self, ident, name, description): > self.ident = ident > self.name = name > self.description = description > > class DataSourceItem(object): > def __init__(self, ident, name, description, data_source): > self.ident = ident > self.name = name > self.description = description > self.data_source = data_source
That's a clear job for single inheritance: class DataSourceItem(BaseItem): def __init__(self, ident, name, description, data_source): BaseItem.__init__(self, ident, name, description) self.data_source = data_source Note: there's a BIG question mark as to whether you should use super() or not when inheriting methods. I've previously defended the use of super() even in single-inheritance classes, where it is not strictly necessary but does no harm. However in this case, the function signature of DataSourceItem and BaseItem are different, which is a clear signal *not* to use super(). But if you're brave, here's a version that uses super(): class DataSourceItem(BaseItem): def __init__(self, ident, name, description, data_source): super(DataSourceItem, self).__init__(ident, name, description) self.data_source = data_source Is this safe? Well, probably, for the simple class hierarchy you enter. But if you extend the class hierarchy with more sibling and child classes, perhaps not. > class BaseItemCollection(list): > def __init__(self, ident, name, description): > self.ident = ident > self.name = name > self.description = description > def default_version(self): > return self[-1] That's a clear job for composition: class BaseItemCollection(list): def __init__(self, ident, name, description): self.data = BaseItem(ident, name, description) def default_version(self): return self[-1] > class BaseDataSourceItemCollection(list): > def __init__(self, ident, name, description, data_source): > self.ident = ident > self.name = name > self.description = description > self.data_source = data_source > def default_version(self): > return self[-1] This one isn't clear. You could inherit either directly from list: class BaseDataSourceItemCollection(list): def __init__(self, ident, name, description, data_source): self.data = DataSourceItem( ident, name, description, data_source) def default_version(self): return self[-1] or from BaseItemCollection: class BaseDataSourceItemCollection(BaseItemCollection): def __init__(self, ident, name, description, data_source): BaseItemCollection.__init__(self, ident, name, description) self.data_source = data_source Which such trivially small classes, there's no real advantage or disadvantage to either. Of course, you could use multiple inheritance, but that opens a whole rat's nest of difficulties. Even though Python makes it easy to implement multiple-inheritance, it is full of pitfalls for the unwary, and even the wary, so you should always consider whether you *really* need it. Other alternatives are traits and generic functions: http://www.artima.com/weblogs/viewpost.jsp?thread=246488 http://www.artima.com/weblogs/viewpost.jsp?thread=237764 Lastly, I should mention automatic delegation as an alternative to inheritance. It's not clear to me that this would be either useful or necessary for your classes, but I'll mention it so you can google for more information if you are interested. -- Steven D'Aprano _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor