3 ms·
> It has closures, but until py3, they clashed with the implicit declaration syntax. Could you elaborate on what you mean, here? The only issue I know of with
by jmillikin 17y ago
> It has closures, but until py3, they clashed with the implicit declaration syntax.
Could you elaborate on what you mean, here? The only issue I know of with Python 2's closures is that there's no scoping keyword for non-local, non-global variables. But that only matters if you're trying to re-define variables in a parent procedure's scope, which is probably not a good idea.
- andreyf 17y agoIt's a great idea if you want to make small callable objects with limited (hidden) state, in a way that's easy to translate between any languages which support closures. For example, in JS: function gencycle() { var args = Array.prototype.slice.apply(arguments), i = 0; return function cycle() { i = (i+1) % args.length; return args[i]; } } I can then use gencycle("red", "green", "blue") when I want a function which gives me a rotation of colors. In py26, I'd write it as: class GenCycle(object): def __init__(self, *args): super(GenCycle, self).__init__() self.args = args self.i = 0 def __call__(self): self.i = (self.i+1) % len(self.args) return self.args[self.i] In Python 3, I'd have to choose between the two versions.
- j_baker 17y ago>>> from itertools import cycle >>> iter = cycle(['red', 'green', 'blue']) >>> iter.next() 'red' >>> iter.next() 'green' >>> iter.next() 'blue' >>> iter.next() 'red'
- jmillikin 17y agoI believe he's using cycle() as a simple example, to illustrate a more complex requirement.
- jmillikin 17y agoThe preferred way to do that in Python is as a co-routine (AKA generator). Besides being easier to read and reason about, generators implement common protocols, such as the iteration protocol. This means you can use generators in for-loops, as a parameter to list(), or anywhere else that accepts an iterator. Here's an example of cycle() as a co-routine: def cycle(*args): i = 0 while True: i = (i + 1) % len (args) yield args[i] for arg in cycle("red", "green", "blue"): print (arg) Alternatively, if you really want to use a callable: gencycle = lambda *args: cycle(*args).next get_next = gencycle("red", "green", "blue") print (get_next()) print (get_next()) print (get_next()) Either way, it'll be cleaner than an explicitly stateful object.