How exactly does Python evaluate class attributes? I\'ve stumbled across an interesting quirk (in Python 2.5.2) that I\'d like explained.
I have a class with some a
Yeah, it's a bit dodgy, this. A class doesn't really introduce a new scope, it just sort of looks a little bit like it does; constructs like this expose the difference.
The idea is that when you're using a generator expression it's equivalent to doing it with a lambda:
class Brie(object):
base= 2
powers= map(lambda i: base**i, xrange(5))
or explicitly as a function statement:
class Brie(object):
base= 2
def __generatePowers():
for i in xrange(5):
yield base**i
powers= list(__generatePowers())
In this case it's clear that base
isn't in scope for __generatePowers
; an exception results for both (unless you were unlucky enough to also have a base
global, in which case you get a wrongness).
This doesn't happen for list comprehensions due to some internal details on how they're evaluated, however that behaviour goes away in Python 3 which will fail equally for both cases. Some discussion here.
A workaround can be had using a lambda with the same technique we relied on back in the bad old days before nested_scopes:
class Brie(object):
base= 2
powers= map(lambda i, base= base: base**i, xrange(5))