On Sun, Aug 3, 2014 at 11:41 PM, Marko Rauhamaa <ma...@pacujo.net> wrote: > Steven D'Aprano <steve+comp.lang.pyt...@pearwood.info>: > And I'm talking about a third kind: object-based. It is in active > (albeit limited) use in scheme: <URL: http://irreal.org/blog/?p=40>. I'm > currently using the principle in a project of mine. > > In Java, you use anonymous classes for the same thing. In Python, you > can think of the principle as one-time classes. So instead of writing:
In my experience, 99% of the time when anonymous classes are used, they only contain one method. That's because they're not really being used to implement some interface abstractly; they mostly exist to provide a means of specifying a callback function in a language where functions aren't first-class. > > class A: > def __init__(self, x, y, z): > self.x = x > self.d = y * y + z * z > > def f(self): > return self.x - self.d > > you write: > > def A(x, y, z): > d = y * y + z * z > > class Anonymous: > def f(self): > return x - d > > return Anonymous() And it's the same thing here. This isn't an interface. It's a function, so just return a function and be done with it. And in the rare event that you actually mean to implement more than one method, then you have enough functionality localized that it's probably worthwhile to just name it and make it an actual class. > Now, if you always did this, you would notice that classes are > unnecessary clutter and would call for syntax like this: > > def A(x, y, z): > d = y * y + z * z > return object: > def f(): > return x - d The presence of "object" here feels totally unnecessary to me. If the point is to avoid having a class, then why create a class? In this case you could easily just return a function. To take a more complex case, say the Scheme make-queue constructor that you linked to, you could still just return a function; the same could be implemented in Python 3 as: def make_queue(): front = [] back = [] def queue_command(command, data=None): def exchange(): nonlocal front, back front = back; front.reverse() back = [] if command == 'push': back.append(data) elif command == 'pop': if not front: exchange() return front.pop() elif command == 'peek': if not front: exchange() return front[-1] elif command == 'show': return str(list(reversed(front)) + back) else: raise ValueError('Illegal command to queue object ' + command) queue_command.push = lambda data: queue_command('push', data) queue_command.pop = lambda: queue_command('pop') queue_command.peek = lambda: queue_command('peek') return queue_command >>> queue = make_queue() >>> queue.push(1) >>> queue.push(2) >>> queue.pop() 1 >>> queue.push(3) >>> queue.push(4) >>> queue.pop() 2 >>> queue.peek() 3 >>> queue.pop() 3 >>> queue.pop() 4 -- https://mail.python.org/mailman/listinfo/python-list