Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!multikabel.net!newsfeed20.multikabel.net!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!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.007 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'apis': 0.07; 'subject:adding': 0.07; 'python': 0.09; 'alternatives': 0.09; 'components:': 0.09; 'other,': 0.09; 'src,': 0.09; 'cc:addr :python-list': 0.10; 'def': 0.10; 'component': 0.15; 'interfaces': 0.15; '@classmethod': 0.16; 'dest)': 0.16; 'paradigm.': 0.16; 'registry': 0.16; 'satisfying': 0.22; 'work,': 0.22; 'cc:2**0': 0.23; 'raise': 0.24; 'random': 0.24; 'cc:no real name:2**0': 0.24; 'idea': 0.24; 'cc:addr:python.org': 0.25; 'header:In-Reply-To:1': 0.25; '(e.g.': 0.27; 'components': 0.27; 'message- id:@mail.gmail.com': 0.27; 'interface': 0.27; 'asks': 0.29; 'class': 0.29; 'maybe': 0.29; 'point': 0.31; 'gets': 0.32; 'switch': 0.32; 'could': 0.32; 'interaction': 0.33; 'like:': 0.33; 'point,': 0.33; 'handle': 0.33; 'themselves': 0.33; 'received:google.com': 0.34; 'thanks': 0.34; 'clear': 0.35; 'received:209.85': 0.35; 'something': 0.35; 'there': 0.35; 'really': 0.36; 'but': 0.36; 'uses': 0.37; 'being': 0.37; 'received:209': 0.37; 'subject:: ': 0.38; 'some': 0.38; 'things': 0.38; 'instead': 0.39; 'called': 0.39; 'short': 0.39; 'skip:" 10': 0.40; 'header:Received:5': 0.40; 'easy': 0.60; 'provide': 0.62; 'different': 0.63; 'skip:n 10': 0.63; 'become': 0.65; 'life': 0.66; 'easier,': 0.84; 'subject:mode': 0.84; 'hand.': 0.91 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=qbg8oMK3HHqU8eLToCiHWNUoRFDK8SlblzAO6r0dmns=; b=bHqTQMDILCA3EKy56MASPBnOOZfULemvlSFfZQtJ/Y4M0cGPj+SvWe+21FOnYjr2S5 YssClspyFSeA/btFnfoYLsy3UVRj8pBIoqhT4O8yyw9lYTBNCg1D+h+wj5n5Tf6PKgrE nu0Lb0rJlyHNG6RQFpUfdUrLpoP8lnRBaLL80Nl2OWBp6tt76SjQCABsWlRiIjJJDYnG RINnuXS7whpcQOd9tUBHwDLtk5E4x6CXX3Q8FS7DUF7xUEUWxapRsJk9fUwznIwVdaUW hf+5XYJKCvnMRrHmOQqYW9fuoCJ/u4HCDIY/MXpZlggJf6gl0db5OkuPUhIsh582aZDQ ozPA== MIME-Version: 1.0 In-Reply-To: <87liiyr48f.fsf@handshake.de> References: <87liiyr48f.fsf@handshake.de> Date: Thu, 5 Jul 2012 10:22:02 +0100 Subject: Re: adding a simulation mode From: andrea crotti To: Dieter Maurer Content-Type: text/plain; charset=ISO-8859-1 Cc: python-list@python.org 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: 48 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1341480568 news.xs4all.nl 6976 [2001:888:2000:d::a6]:55403 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:24905 2012/7/5 Dieter Maurer : > > There is a paradigm called "inversion of control" which can be used > to handle those requirements. > > With "inversion of control", the components interact on the bases > of interfaces. The components themselves do not know each other, they > know only the interfaces they want to interact with. For the interaction > to really take place, a component asks a registry "give me a component > satisfying this interface", gets it and uses the interface. > > If you follow this paradigm, it is easy to switch components: just > register different alternatives for the interface at hand. > > > "zope.interface" and "zope.component" are python packages that > support this paradigm. Despite the "zope" in their name, they can be > used outside of "Zope". > > "zope.interface" models interfaces, while "zope.component" provides > so called "utilities" (e.g. "database utility", "filesystem utility", ...) > and "adapters" and the corresponding registries. > > > Of course, they contain only the infrastructure for the "inversion of control" > paradigm. Up to you to provide the implementation for the various > mocks. > Thanks that's a good point, in short I could do something like: class FSActions: @classmethod def copy_directories(cls, src, dest) raise NotImplementedError @classmethod .... And then have different implementations of this interface. This would work, but I don't really like the idea of constructing interfaces that provide only the few things I need. Instead of being good APIs they might become just random functionalities put together to make my life easier, and at that point maybe just some clear mocking might be even better..