Received: by 10.66.75.39 with SMTP id z7mr3378668pav.26.1349563536111; Sat, 06 Oct 2012 15:45:36 -0700 (PDT) Path: t10ni23619476pbh.0!nntp.google.com!news.glorb.com!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-l...@python.org Delivered-To: python-l...@mail.python.org X-Spam-Status: OK 0.013 X-Spam-Evidence: '*H*': 0.97; '*S*': 0.00; 'anyway.': 0.04; 'method.': 0.05; 'classes.': 0.07; 'python': 0.09; 'interpreter,': 0.09; 'subclass': 0.09; 'subclasses': 0.09; 'url:github': 0.09; 'cc:addr :python-list': 0.10; 'cases': 0.15; "hasn't": 0.15; 'interfaces': 0.15; '*only*': 0.16; 'habits,': 0.16; 'instantiate': 0.16; 'wrote:': 0.17; '(not': 0.20; 'import': 0.21; 'not,': 0.21; 'filled.': 0.22; 'cc:2**0': 0.23; 'mention': 0.23; "i've": 0.23; 'seems': 0.23; 'cc:addr:python.org': 0.25; 'header:In-Reply-To:1': 0.25; 'header:User-Agent:1': 0.26; '(which': 0.26; 'common': 0.26; 'execution': 0.27; 'skip:@ 10': 0.27; 'interface': 0.27; "doesn't": 0.28; 'far.': 0.29; 'mind,': 0.29; 'oop': 0.29; 'overhead': 0.29; 'skip:_ 10': 0.29; 'class': 0.29; "i'm": 0.29; 'classes': 0.30; 'error': 0.30; 'feedback': 0.30; 'code': 0.31; 'point': 0.31; 'implement': 0.32; 'generally': 0.32; 'received:209.85.160.46': 0.32; 'getting': 0.33; 'strict': 0.33; 'another': 0.33; 'received:google.com': 0.34; 'thanks': 0.34; 'fail': 0.35; 'doing': 0.35; 'expected': 0.35; 'pm,': 0.35; 'received:192.168.0': 0.35; 'subject:?': 0.35; 'received:209.85': 0.35; 'but': 0.36; 'message-id:@gmail.com': 0.36; 'child': 0.36; 'anything': 0.36; 'should': 0.36; 'enough': 0.36; 'itself': 0.37; 'uses': 0.37; 'being': 0.37; 'rather': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'unit': 0.38; 'easier': 0.38; 'some': 0.38; 'things': 0.38; 'received:192': 0.39; 'little': 0.39; 'received:192.168': 0.40; 'subject:-': 0.40; 'header:Received:5': 0.40; 'your': 0.60; 'more.': 0.62; 'back': 0.62; 'time,': 0.62; 'making': 0.64; 'virtually': 0.65; 'due': 0.66; 'overall': 0.66; 'talking': 0.66; '*really*': 0.84; 'intentions': 0.84; 'moot': 0.84; 'tie': 0.84; 'together,': 0.84; 'abc': 0.91; 'subject:Are': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=HaXYRH2UeBc+fpmIj2gqk2xVsRFL31hZ9ivtlHq+EN0=; b=AS1B+nxkgz4lQbXQD5GucJeYtmywsryihWgmAoAEVDe0Wu6FTVbRTuWdOVGpG++Xc5 oPUNpetOE028Ko5rGM5Srso/qcsswvZaX6hidMv1BhYHRfF62tcwGQAH0FSC+kZHMm8H gSJUKA1X79MbcPwttrJrgijdBYQzYt+vt+0DL/v0SjLWNRp+9DlJnvQH/Ts9nW5woQqO S6iAOSpCp6Vljw2Q8XQp24Gkmxg5WApk+utERRpLfX/jESKzm0mJCTHrKKbTQN1m8tgT KR2t3HqUwAudcfFp5iyDOb0V+YHWen7YOwYKRU8yBtC7jeLamMO0W0YTzR5C79anlM8Y HTdg== Date: Sat, 06 Oct 2012 15:45:23 -0700 From: Demian Brecht User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:15.0) Gecko/20120912 Thunderbird/15.0.1 MIME-Version: 1.0 To: Trent Nelson Subject: Re: Are ABCs an anti-pattern? References: <506AF8C9.8060...@gmail.com> <20121005195836.GA94...@snakebite.org> In-Reply-To: <20121005195836.GA94...@snakebite.org> Cc: Python X-BeenThere: python-l...@python.org X-Mailman-Version: 2.1.15 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: 43 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1349563535 news.xs4all.nl 6944 [2001:888:2000:d::a6]:40209 X-Complaints-To: ab...@xs4all.nl Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit On 12-10-05 12:58 PM, Trent Nelson wrote: > I like them. In particular, I like that I can enumerate all the > subclasses that happen to implement the ABC via the metaclass's > __subclasses__() method. As long as you have a common base class (which in your case is a requirement), then __subclasses__ works for introspecting child classes. It doesn't *really* have anything to do with abcs. > I also like that I can trust Python > not to instantiate a subclass of an ABC unless it meets all the > interface criteria I've stipulated. Another way to read this is that you don't trust those using your code to be bright enough to understand what your code is doing and what it requires. In my mind, this seems to somewhat contradict the philosophy of "we're all consenting adults here". Whether you utilize interfaces or not, code should be documented. Your documentation would be responsible for laying out the expected interface (again, whether you're using the interfaces or not). Code would fail at some point if a requirement on an interface hasn't been filled. The *one* nice thing is that it'll error on import rather than execution time, but to me, if your code is unit tested, then all these things should be caught almost immediately anyway. From my experience (again, *only* talking about Python here), it seem to me that less is generally more. Less code means less things to read and tie together, making it easier to grok overall (not to mention less overhead for the interpreter, but that's virtually moot due to the *very* little overhead in 99% of cases of uses features such as abcs). Using abcs not only lends itself to code bloat, but it also leads to over-engineering as once you fall into old OOP habits, you start getting back to un-Pythonic code (pretty subjective statement, I know :)). Again, please don't misunderstand my intentions here. I'm not arguing the need for abstract base classes in a strict OOP world. I'm arguing them as not genuinely being Pythonic. Thanks for your the feedback so far. -- Demian Brecht @demianbrecht http://demianbrecht.github.com