On Tue, Mar 29, 2016 at 3:45 PM, Marko Rauhamaa <ma...@pacujo.net> wrote: > Chris Angelico <ros...@gmail.com>: > >> On Tue, Mar 29, 2016 at 12:40 AM, Marko Rauhamaa <ma...@pacujo.net> wrote: >>> Dan Sommers <d...@tombstonezero.net>: >>> >>>> 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) = 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: > > ======================================================================== > def process(self, source): > awk = 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(fields): > yield [ fields[i] for i in awk.columns ] > return Source(self.encoding, self.errors, self.eol, > self.delim) > ======================================================================== > > Here's another, older one: > > ======================================================================== > def __init__(self, server, sock, domain, peer): > super().__init__(server, sock) > conn = self > client_ip = 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 = None > conn.set_state(ZOMBIE) > > def handle_spf_verdict(self, verdict, reason, *capabilities): > conn.resume() > conn.log("verdict {} reason {}".format(verdict, reason)) > # RFC 4408 ยง2.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(reason)) > conn.set_state(IDLE) > return > conn.respond(250, server.domain, *capabilities) > conn.set_state(IDLE) > ========================================================================
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 -- https://mail.python.org/mailman/listinfo/python-list