I think I understand the answers well enough. What I *really*
don't understand is why this particular "feature" of Python (i.e.
that functions defined within a class statement are forbidden from
"seeing" other identifiers defined within the class statement) is
generally considered to be perfectly OK. IMO it's a bizarre,
inexplicable blindspot (which, among other things, gives rise to
a certain worry about what other similar craziness lurks under
Python's image of rationality). I have never seen even a half-hearted
justification, from a language design point of view, for why this
particular "feature" is worth having.
Guido's design justifications:
http://mail.python.org/pipermail/python-dev/2000-November/010598.html
--
My personal justification:
Python has used the same basic method of class creation since the very
beginning: create a new local namespace, execute the class suite in
that namespace, and then create a class, using the contents of the
namespace as the class attributes. The important thing to note here
is that there are really *two* namespaces--the local namespace that
exists while the class suite is being executed (what I call the "suite
namespace"), and the namespace of the class itself--and the first
ceases to exist when the second is created. The two namespaces
generally contain the same names at the point that the transfer
occurs, but they don't have to; the metaclass (which constructs the
class) is free to mess with the dictionary of attributes before
creating the class.
Suppose for a moment that the suite namespace *were* visible to nested
scopes. The simplest and most consistent implementation would be to
have a closure generated by a class statement be similar to that
generated by a function--i.e., the closure would be over the suite
namespace. This hardly seems desirable, though, because the suite
namespace and the class namespace would get out of sync when different
objects were assigned to the class namespace:
class C:
x = 1
def foo(self):
print x
print self.x
1
2
Surely such an implementation would be considered an even larger
Python wart then not having the suite namespace visible to nested
scopes at all. But it's better than the alternative of trying to
unify the class suite namespace and the class namespace, which would
be a nightmare of special cases (adding/deleting class attributes?
descriptors? __getattr__?) and require an implementation completely
separate from that of normal nested scopes.
-Miles
P.S. Just for fun:
import types
def make_class(*bases):
"""Decorator to allow you to (ab)use a function as a class definition.
The function must take no arguments and end with 'return locals()';
bases are (optionally) specified as arguments to make_class;
metaclasses other than 'type' are not supported.
.... def C():
.... greeting = 'Hello'
.... target = 'world'
.... def greet(self):
.... print '%s, %s' % (self.greeting, target)
.... return locals()
....Hello, world
"""
def decorator(func):
return type(func.func_name, bases, func())
if len(bases) == 1 and isinstance(bases[0], types.FunctionType):
func = bases[0]
bases = (object,)
return decorator(func)
if not bases:
bases = (object,)
return decorator