Le Tuesday 12 August 2008 11:29:18 Cousson, Benoit, vous avez écrit : > Hi, > > I'd like to be able to use a nested class (C1) from another sibling nested > class (C3). This looks very similar to the nested scopes of functions > except that it does not work. > > class A(object): > pass > > class B(object): > > class C1(object): > pass > > class C2(C1): > foo = A > > class C3(object): > foo = C1 > > The funny thing is that C2 can inherit from C1 but C3 cannot reference C1. > B.C1 does not work either, but in that case it makes sense since B is still > being defined. Is this a language limitation or something that does not > make sense at all? >
This is a language limitation. This is because nested scope is implemented for python function only since 2.3 allow late binding of free variables. the scope in class statment is not a closure, so there is only two possible scope in it : local and global. When "class C2(C1):" statment is interpreted, it is in the scope of class B for which a name C1 exists, but it doesn't within the new scope of class C2 (the future C2.__dict__). If you really need such a nested thing, this could help : >>>[39]: class A(object) : class B(object) : pass C = type('C', (B,), {'ref' : B}) ....: >>>[29]: >>>[30]: A ...[30]: <class '__main__.A'> >>>[31]: A.B ...[31]: <class '__main__.B'> >>>[32]: A.C ...[32]: <class '__main__.C'> >>>[33]: A.C.__bases__ ...[33]: (<class '__main__.B'>,) >>>[34]: A.C.ref ...[34]: <class '__main__.B'> > I'm wondering as well if the new nonlocal statement will fix that in py3k? > nonlocal doesn't adress this issue an I doubt python 3.0 fix it at all. You have the same problem with generator expressions, which bind lately outer loop variables : >>>[70]: def f() : l = list( a for a in range(5) ) return list( e + f for f in range(5) for e in l ) ....: >>>[73]: list(f()) ...[73]: [0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8] >>>[74]: class A(object) : l = list( a for a in range(5) ) m = [ e + f for f in range(5) for e in l ] ....: ....: >>>[77]: A.m ...[77]: [0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 2, 3, 4, 5, 6, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8] >>>[78]: class A(object) : l = list( a for a in range(5) ) m = list( e + f for f in range(5) for e in l ) ....: ....: --------------------------------------------------------------------------- NameError Traceback (most recent call last) /home/maric/<ipython console> in <module>() /home/maric/<ipython console> in A() /home/maric/<ipython console> in <genexpr>((f,)) NameError: global name 'l' is not defined -- _____________ Maric Michaud -- http://mail.python.org/mailman/listinfo/python-list