Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!news.albasani.net!feeder.news-service.com!newsfeed.xs4all.nl!newsfeed6.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'sorts': 0.04; '(although': 0.05; 'classes.': 0.05; 'behavior.': 0.07; 'python': 0.07; 'decorator': 0.09; 'from:addr:ethan': 0.09; 'from:addr:stoneleaf.us': 0.09; 'from:name:ethan furman': 0.09; 'message-id:@stoneleaf.us': 0.09; 'okay': 0.09; 'received:74.54.199': 0.09; 'received:74.54.199.50': 0.09; 'received:gator410.hostgator.com': 0.09; '~ethan~': 0.09; 'written': 0.12; 'wrote:': 0.14; "django's": 0.16; 'received:72.11': 0.16; 'received:72.11.125': 0.16; 'received:72.11.125.166': 0.16; 'testcase': 0.16; 'testcases': 0.16; 'whole,': 0.16; 'class,': 0.16; 'possibly': 0.16; 'fine': 0.18; "'python": 0.19; 'describes': 0.19; 'cc:2**0': 0.20; 'code': 0.22; 'header:In-Reply-To:1': 0.22; 'cc:addr:python-list': 0.22; 'trying': 0.23; 'example': 0.24; 'calling': 0.25; "i'll": 0.26; 'classes': 0.26; 'object': 0.27; 'class': 0.29; 'probably': 0.30; 'implement': 0.30; 'cc:addr:python.org': 0.31; 'model': 0.31; 'carl': 0.31; 'construct': 0.31; 'called': 0.32; 'another': 0.32; 'source': 0.32; '...': 0.32; 'using': 0.34; 'header:User-Agent:1': 0.35; 'too': 0.36; 'rather': 0.36; 'case,': 0.36; 'problems': 0.37; 'some': 0.37; 'thread': 0.38; 'goes': 0.38; 'used': 0.38; 'though': 0.38; 'works': 0.40; "it's": 0.40; 'header:Received:5': 0.40; 'might': 0.40; 'owns': 0.60; 'received:74.54': 0.60; 'exact': 0.60; 'act': 0.61; 'taking': 0.61; 'give': 0.61; 'upon': 0.63; 'received:hostgator.com': 0.64; 'received:websitewelcome.com': 0.71; 'received:69.56': 0.77; 'common,': 0.84; 'composition': 0.84; 'received:gateway16.websitewelcome.com': 0.84; 'to:none': 0.92 Date: Thu, 28 Apr 2011 18:43:35 -0700 From: Ethan Furman User-Agent: Thunderbird 1.5.0.10 (Windows/20070221) MIME-Version: 1.0 CC: Python Subject: Re: Composition instead of inheritance References: In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - gator410.hostgator.com X-AntiAbuse: Original Domain - python.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - stoneleaf.us X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: mail.admailinc.com ([192.168.10.136]) [72.11.125.166]:2082 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 36 NNTP-Posting-Host: 82.94.164.166 X-Trace: 1304040768 news.xs4all.nl 41110 [::ffff:82.94.164.166]:48276 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:4283 Carl Banks wrote: > That's not what we mean by composition. Composition is when one object > calls upon another object that it owns to implement some of its behavior. > Often used to model a part/whole relationship, hence the name. Hmmm. Okay -- any ideas for a better term? Something that describes taking different source classes and fusing them into a new whole, possibly using single-inheritance... Frankenstein, maybe? ;) > The sorts of class that this decorator will work for are probably not > the ones that are going to have problems cooperating in the first place. > So you might as well just use inheritance; that way people trying to read > the code will have a common, well-known Python construct rather than a > custom decorator to understand. From thread 'python and super' on Python-Dev: Ricardo Kirkner wrote: > I'll give you the example I came upon: > > I have a TestCase class, which inherits from both Django's TestCase > and from some custom TestCases that act as mixin classes. So I have > something like > > class MyTestCase(TestCase, Mixin1, Mixin2): > ... > > now django's TestCase class inherits from unittest2.TestCase, which we > found was not calling super. This is the type of situation the decorator was written for (although it's too simplistic to handle that exact case, as Ricardo goes on to say he has a setUp in each mixin that needs to be called -- it works fine though if you are not adding duplicate names). ~Ethan~