Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!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.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'example:': 0.03; 'api.': 0.05; 'explicitly': 0.05; 'explicit': 0.07; 'mouse': 0.07; 'from:addr:ethan': 0.09; 'from:addr:stoneleaf.us': 0.09; 'from:name:ethan furman': 0.09; 'message-id:@stoneleaf.us': 0.09; 'received:184.172': 0.09; 'received:gator410.hostgator.com': 0.09; 'subject:design': 0.09; 'used)': 0.09; 'window.': 0.09; '~ethan~': 0.09; 'developer': 0.10; 'api': 0.11; 'subject:Help': 0.11; 'python': 0.11; 'gui': 0.12; 'changes': 0.15; 'windows': 0.15; '"right"': 0.16; "'a',": 0.16; "'s')": 0.16; 'backwards': 0.16; 'command,': 0.16; 'invocation': 0.16; 'it),': 0.16; 'magic': 0.16; 'michael,': 0.16; 'script,': 0.16; 'subject:API': 0.16; 'world!")': 0.16; 'wrote:': 0.18; 'library': 0.18; 'everyone,': 0.19; 'starts': 0.20; 'written': 0.21; 'example': 0.22; 'import': 0.22; 'header:User-Agent:1': 0.23; 'helpful': 0.24; '(or': 0.24; 'switch': 0.26; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'michael': 0.29; 'respective': 0.29; 'change,': 0.30; "i'm": 0.30; '(which': 0.31; 'go.': 0.31; 'allows': 0.31; 'text': 0.33; 'open': 0.33; 'computer.': 0.33; 'sense': 0.34; 'could': 0.34; 'subject: (': 0.35; 'good.': 0.35; 'objects': 0.35; 'operations': 0.35; 'but': 0.35; 'add': 0.35; 'version': 0.36; 'object,': 0.36; 'charset:us-ascii': 0.36; 'possible': 0.36; 'operating': 0.37; 'two': 0.37; 'being': 0.38; 'window': 0.38; 'whatever': 0.38; 'to:addr:python-list': 0.38; 'pm,': 0.38; 'extremely': 0.39; 'to:addr:python.org': 0.39; 'called': 0.40; 'how': 0.40; 'commands': 0.60; 'break': 0.61; 'received:173': 0.61; 'simple': 0.61; 'you.': 0.62; 'name': 0.63; 'such': 0.63; 'our': 0.64; 'design,': 0.64; 'more': 0.64; 'different': 0.65; 'between': 0.67; '(yet)': 0.84; 'commands.': 0.84; 'expose': 0.84 Date: Mon, 25 Mar 2013 16:11:34 -0700 From: Ethan Furman User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130106 Thunderbird/17.0.2 MIME-Version: 1.0 To: python-list@python.org Subject: Re: Help me pick an API design (OO vs functional) References: <68da956e-ebe0-4f58-92cd-f7ffff0075b4@googlegroups.com> In-Reply-To: <68da956e-ebe0-4f58-92cd-f7ffff0075b4@googlegroups.com> Content-Type: text/plain; charset=us-ascii; 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-BWhitelist: no X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: ([173.12.184.235]) [173.12.184.235]:37768 X-Source-Auth: ethan+stoneleaf.us X-Email-Count: 1 X-Source-Cap: dG9idWs7dG9idWs7Z2F0b3I0MTAuaG9zdGdhdG9yLmNvbQ== X-BeenThere: python-list@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: 36 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1364253688 news.xs4all.nl 6929 [2001:888:2000:d::a6]:51261 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:41835 On 03/25/2013 12:29 PM, Michael Herrmann wrote: > Hello everyone, > > my name is Michael, I'm the lead developer of a Python GUI automation library for Windows called Automa: http://www.getautoma.com. We want to add some features to our library but are unsure how to best expose them via our API. It would be extremely helpful for us if you could let us know which API design feels "right" to you. > > Our API already offers very simple commands for automating the GUI of a Windows computer. For example: > > from automa.api import * > start("Notepad") > write("Hello World!") > press(CTRL + 's') > write("test.txt", into="File name") > click("Save") > click("Close") > > When you execute this script, Automa starts Notepad and simulates key strokes, mouse movements and clicks to perform the required commands. At the moment, each action is performed in the currently active window. > > We do not (yet) have a functionality that allows you to explicitly switch to a specific window. Such a functionality would for instance make it possible to open two Notepad windows using the start(...) command, and copy text between them. > > One API design would be to have our start(...) function return a "Window" (say) object, whose methods allow you to do the same operations as the global functions write(...), press(...), click(...) etc., but in the respective window. In this design, the example of operating two Notepad windows could be written as > > notepad_1 = start("Notepad") > notepad_2 = start("Notepad") > notepad_1.write("Hello World!") > notepad_1.press(CTRL + 'a', CTRL + 'c') > notepad_2.press(CTRL + 'v') This is the way to go. Just move your global functions into the Window object (or whatever you call it), break backwards compatibility (major version number change, perhaps?), and call it good. It makes much more sense to call methods of several different objects (which is explicit -- you always know which object is being used) than having a magic function that changes the object in the background (plus you now have to search backwards for the last magic invocation to know -- and what if a called function changes it?). -- ~Ethan~