Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed3.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; 'python.': 0.02; 'talks': 0.03; 'say,': 0.05; 'decorator': 0.09; 'function,': 0.09; 'function:': 0.09; 'will,': 0.09; 'def': 0.12; "(i'm": 0.16; 'called,': 0.16; 'closure,': 0.16; 'closures': 0.16; 'closures,': 0.16; 'context:': 0.16; 'foo()': 0.16; 'foo():': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'func': 0.16; 'lambda': 0.16; 'loops': 0.16; 'sorts': 0.16; 'sugar': 0.16; 'sure.': 0.16; 'syntactic': 0.16; 'worst': 0.16; 'language': 0.16; 'wrote:': 0.18; 'work,': 0.20; '>>>': 0.22; 'programming': 0.22; 'python?': 0.22; 'separate': 0.22; 'print': 0.22; 'connected': 0.24; 'together.': 0.24; "i've": 0.25; 'this:': 0.26; 'pass': 0.26; 'header:In-Reply-To:1': 0.27; 'function': 0.29; 'correct': 0.29; 'wondering': 0.29; 'am,': 0.29; 'tim': 0.29; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'that.': 0.31; 'context.': 0.31; 'languages': 0.32; 'another': 0.32; 'quite': 0.32; 'fri,': 0.33; 'not.': 0.33; "can't": 0.35; 'classes': 0.35; 'common': 0.35; 'no,': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'earth': 0.36; 'subject:?': 0.36; 'two': 0.37; 'lists.': 0.38; 'to:addr:python-list': 0.38; 'does': 0.39; 'functional': 0.39; 'to:addr:python.org': 0.39; 'even': 0.60; 'read': 0.60; 'happen': 0.63; 'more': 0.64; 'articles': 0.65; 'different.': 0.84; 'hardly': 0.84; 'way)': 0.84; 'hand,': 0.93; '2013': 0.98 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 :content-type; bh=ue/sAY8VHQMUvPE+RxYzXI7WUQ46v3wOgNRl88a8DoE=; b=s6xa3Qn8DUs6xpC3/6+Rr5q92o/tSpJ08u4HrUlkUEerSqIsheKhgCOfhOkNwaDKog cdB/BDLAy1hqnWrlUR7n+ppAXI5jCfuVn6RKC5yYwxNQNS/Jg0F8BpJv5rPc8n+8ZI/9 JhEqOiZRr0hXj4OtXKGY0o2JGeOidudujXtCvzktIAqUmIJKIBoQFm3yPSK9igS0lcKx Pfm1LVPSaZ9MnXdCTHttxBAdIg41zSOLrlsGSPgsAxng0XEvZJETXq1MzdhX/j3r78OK umt5ShdgadQ59px+Q1EtPqFu1jx0GVTY+4vi96AWl6+904FFsU2OFMMsWwiHHG4qBTJz ZU7g== MIME-Version: 1.0 X-Received: by 10.66.158.72 with SMTP id ws8mr15922573pab.39.1381413784874; Thu, 10 Oct 2013 07:03:04 -0700 (PDT) In-Reply-To: <707e67a6-c398-4d0a-a058-76b8bf2829f0@googlegroups.com> References: <707e67a6-c398-4d0a-a058-76b8bf2829f0@googlegroups.com> Date: Fri, 11 Oct 2013 01:03:04 +1100 Subject: Re: closure = decorator? From: Chris Angelico To: python-list@python.org Content-Type: text/plain; charset=ISO-8859-1 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: 55 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1381413788 news.xs4all.nl 15893 [2001:888:2000:d::a6]:44864 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:56572 On Fri, Oct 11, 2013 at 12:51 AM, Tim wrote: > I've read a couple of articles about this, but still not sure. > When someone talks about a closure in another language (I'm learning Lua on the side), is that the same concept as a decorator in Python? No, they're quite different. A decorator (let's look at function decorators; classes can have them too, and they work pretty much the same way) is syntactic sugar for this: def func(args): blah blah blah func = decorator(func) You can do all sorts of things with that. Even stupid things: >>> @print def foo(): pass >>> foo is None True Using print as a decorator does work, though hardly usefully :) A closure, on the other hand, is a function that has some extra context: def outer(x): x += 1 def inner(): return x return inner The function inner() "knows" its context. When it's called, it'll use the same value for x that would have been used in the outer function, even though it's a separate function: >>> foo = outer(5) >>> foo() 6 The terminology is that inner() "closes over" x, if I have that correct (I've not been all that big in functional programming and lambda calculus). Someone will correct me if I'm not. It's very common for a decorator to use closures, but the two are completely different. They're no more connected than, say, for loops and lists. They just happen to work well together. Closures in other languages will, as far as I know, be the same thing as closures in Python. (And their presence and functionality in JavaScript leaves me wondering why on earth the 'this' reference can't be considered "closed over" in the same way. But that's hardly the worst of the language's warts.) ChrisA