Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Chris Angelico Newsgroups: comp.lang.python Subject: Re: List of Functions Date: Tue, 29 Mar 2016 16:00:06 +1100 Lines: 105 Message-ID: References: <3c44f0f8-d701-463e-bf2c-f5871c51bddf@googlegroups.com> <87bn5z1mkd.fsf@bsb.me.uk> <87mvpjx9kh.fsf@elektro.pacujo.net> <87twjqn2jn.fsf@elektro.pacujo.net> <874mbpyjrf.fsf@elektro.pacujo.net> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-Trace: news.uni-berlin.de 7NomB8rjB00tfeyqGjahbwNsiLYdymmLhDWpxUZVEPDQ== 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; 'source,': 0.04; '#if': 0.05; 'classes,': 0.05; 'none:': 0.05; 'reason,': 0.07; 'cc:addr:python-list': 0.09; 'failed:': 0.09; 'lambda:': 0.09; 'messing': 0.09; 'objects.': 0.09; 'rfc': 0.09; 'statements': 0.09; 'example:': 0.10; 'skip:= 70': 0.10; ':-)': 0.12; 'def': 0.13; 'languages,': 0.15; 'server,': 0.15; '2016': 0.16; 'awk': 0.16; 'conn': 0.16; 'conn.close()': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'instantiate': 0.16; 'metaclass': 0.16; 'rather,': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'sock)': 0.16; 'sock,': 0.16; 'syntactic': 0.16; 'wrote:': 0.16; 'helper': 0.18; '>>>': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'java': 0.22; 'anonymous': 0.22; "aren't": 0.22; 'class,': 0.22; 'decorator': 0.22; 'function:': 0.22; 'latter': 0.22; 'am,': 0.23; 'header:In-Reply-To:1': 0.24; 'mon,': 0.24; "i've": 0.25; 'example': 0.26; 'chris': 0.26; 'message-id:@mail.gmail.com': 0.27; 'yield': 0.27; 'dan': 0.29; 'innovation.': 0.29; 'received:209.85.213.174': 0.29; 'code': 0.30; 'class.': 0.30; 'skip:s 30': 0.31; 'skip:_ 10': 0.32; 'generally': 0.32; 'older': 0.32; 'realize': 0.32; 'run': 0.33; 'class': 0.33; "d'aprano": 0.33; 'steven': 0.33; 'subject:List': 0.33; 'tue,': 0.34; 'running': 0.34; 'received:google.com': 0.35; 'functions.': 0.35; 'instance': 0.35; 'quite': 0.35; 'sometimes': 0.35; 'but': 0.36; 'instead': 0.36; 'received:209.85': 0.36; 'skip:{ 10': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'method': 0.37; 'received:209.85.213': 0.37; 'received:209': 0.38; 'self': 0.38; 'skip:s 40': 0.38; 'or,': 0.38; 'takes': 0.39; 'rather': 0.39; 'your': 0.60; 'more': 0.63; 'great': 0.63; 'mar': 0.65; 'benefit': 0.66; '>>>>>': 0.66; 'obvious': 0.76; 'chrisa': 0.84; 'construct': 0.84; 'domain,': 0.84; 'regarded': 0.84; 'to:none': 0.91; 'curse': 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:cc :content-transfer-encoding; bh=J1iSuqgh7SDq6msPHJrq0xC2AVNEeOpjStZJSwe5Y+w=; b=D65P9YlSJhbi32+QX9Q+mBGkFmk/6e9A47UT4TD/wdJsaoU+Ftu/0e8vd+9oPhYAng JJhh+Vcz010adoIlW3/7oS0YauCiDGBiVLpZnrtvJxpLAEk/Svglpjgx7k2UJiVqPDkn 5VnM2KGarehQpj7sjPiTlwF9MqV5iDYUasHyr2WXGFSR9ru2SunPGNvVwwC0rKaRGR/u TZmtsTXmjqLZsy2gWND8vqwDbSJatwYsynaGKKXNNMp85E6twLwLlgRjzmPWB82B+NOG eoMGbbLRfG/9eUxlI//SQhT31hKHH64KFPL5VCW4f2Q2feEUzYf+ywndmo0eBxzjQdvo grhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:cc:content-transfer-encoding; bh=J1iSuqgh7SDq6msPHJrq0xC2AVNEeOpjStZJSwe5Y+w=; b=LhrrEDZwPlQJn433hYcoeoposBKFYkvEIeSdu/M1hB0r+NRLwPaOUPWJJkatXDb/51 gy0RZwwKbe6EUz0AX3rcHjKHlmBgAll9CY+BqrsEhZYGLnZmyZxiEfHC2kfBk1ssnGyo XKji0a12c9FZIxjBGy5uCRuPdqz5c8OdDcdpVm8Yxqm02DzuLfOSgUB/yvQW3crrB5/o fggaJ1e76CprdO7QqCkkhlyQC60OfyaFcaFvrF6JHVcDlCRe3NR19AO9JFTlUONQFNkj PGzp2pui2g5lFSBE51t5REXWO1SOc7axA2txGLb8Zr2ty8TFOsphyLQ+r5SoxMYJBl+1 fGKw== X-Gm-Message-State: AD7BkJIPNjcMEnwcmIU3tbgF1J/UGDuOAURsQf5/cbkUdMigq1H7ZARPQeznfQiR+aOYHNmEbnOx9mv26OvbZg== X-Received: by 10.50.43.226 with SMTP id z2mr709311igl.94.1459227607120; Mon, 28 Mar 2016 22:00:07 -0700 (PDT) In-Reply-To: <874mbpyjrf.fsf@elektro.pacujo.net> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:105949 On Tue, Mar 29, 2016 at 3:45 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> On Tue, Mar 29, 2016 at 12:40 AM, Marko Rauhamaa wrot= e: >>> Dan Sommers : >>> >>>> On Mon, 28 Mar 2016 11:58:54 +0300, Marko Rauhamaa wrote: >>>> >>>>> As for Python, I don't feel a great need for anonymous functions. >>>>> However, I keep running into a need for anonymous classes, or, >>>>> rather, classless objects. Not a biggie. I just create a one-off >>>>> inner class and instantiate it, but I do appreciate Java's syntactic >>>>> innovation. >>>> >>>> And I always curse Java for having to create an inner class and a >>>> method when all I need is a simple function. :-) >>>> >>>> I think it's Steven D'Aprano who keeps pointing out that you can >>>> always name your tiny helper functions instead of using lambda: >>>> >>>> def some_complex_function(): >>>> def f(x) =3D x + 2 >>>> some_library_that_wants_a_callback(f) >>>> some_library_that_wants_a_callback(lambda x: x + 2) >>>> >>>> Both calls to some_library_that_wants_a_callback run the same. >>> >>> Yes, but I've come to realize that I quite often need more than a >>> function: I need an object with behavior. The solution is to use a >>> "helper" class. >> >> Can you give an example of code that would benefit from a >> "lambda-class" construct? > > Here's a recent example: > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > def process(self, source): > awk =3D self > class Source(snake.FieldSource): > def emit_fields(self): > for fields in snake.get_fields( > source, awk.encoding, awk.errors, > awk.eol, awk.delim): > if awk.selector is None or awk.selector(field= s): > yield [ fields[i] for i in awk.columns ] > return Source(self.encoding, self.errors, self.eol, self.= delim) > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > Here's another, older one: > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > def __init__(self, server, sock, domain, peer): > super().__init__(server, sock) > conn =3D self > client_ip =3D peer[0] > > [...] > > class SPF_HELO(STATE): > def terminate(self): > conn.resume() > conn.spf_query.cancel() > conn.close() > if conn.timer is not None: > conn.timer.cancel() > conn.timer =3D None > conn.set_state(ZOMBIE) > > def handle_spf_verdict(self, verdict, reason, *capabilities): > conn.resume() > conn.log("verdict {} reason {}".format(verdict, reason)) > # RFC 4408 =C2=A72.5.5 calls for leniency for SoftFail > #if verdict in [ SPFClient.FAIL, SPFClient.SOFT_FAIL ]: > if verdict in [ SPFClient.FAIL ]: > conn.respond(550, "SPF check failed: {}".format(reaso= n)) > conn.set_state(IDLE) > return > conn.respond(250, server.domain, *capabilities) > conn.set_state(IDLE) > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Since those functions have statements in them, there's not going to be any way to construct this class as an expression (short of stupid messing around with exec, which would be a bad idea). So the best you're likely to be able to do is a metaclass or decorator that short-hands the instantiation - or crafting your other code such that it takes the class, rather than an instance of the class. The latter is quite Pythonic, but generally not as well regarded in other languages, sometimes for obvious reasons like "classes aren't first class objects". :) ChrisA