Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #111090 > unrolled thread

Nested class doesn't see class scope

Started bySteven D'Aprano <steve@pearwood.info>
First post2016-07-05 13:20 +1000
Last post2016-07-04 22:43 -0600
Articles 8 — 6 participants

Back to article view | Back to comp.lang.python


Contents

  Nested class doesn't see class scope Steven D'Aprano <steve@pearwood.info> - 2016-07-05 13:20 +1000
    Re: Nested class doesn't see class scope Rustom Mody <rustompmody@gmail.com> - 2016-07-04 20:37 -0700
    Re: Nested class doesn't see class scope Paul Rubin <no.email@nospam.invalid> - 2016-07-04 20:42 -0700
      Re: Nested class doesn't see class scope Ian Kelly <ian.g.kelly@gmail.com> - 2016-07-04 22:37 -0600
    Re: Nested class doesn't see class scope Ian Kelly <ian.g.kelly@gmail.com> - 2016-07-04 22:41 -0600
      Re: Nested class doesn't see class scope Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-07-05 15:40 +1000
        Re: Nested class doesn't see class scope eryk sun <eryksun@gmail.com> - 2016-07-05 12:45 +0000
    Re: Nested class doesn't see class scope Ian Kelly <ian.g.kelly@gmail.com> - 2016-07-04 22:43 -0600

#111090 — Nested class doesn't see class scope

FromSteven D'Aprano <steve@pearwood.info>
Date2016-07-05 13:20 +1000
SubjectNested class doesn't see class scope
Message-ID<577b2768$0$1606$c3e8da3$5496439d@news.astraweb.com>
I got this in Python 3.6:


py> class A:
...     var = 999
...     print(var)  # succeeds
...     class B:
...         x = var
...
999
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in A
  File "<stdin>", line 4, in B
NameError: name 'var' is not defined


I expected that `var` would be available during the construction of B, just
as it was available inside A, but not to methods inside B. Obviously my
expectations are invalid. Can anyone explain the actual behaviour?



-- 
Steven
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

[toc] | [next] | [standalone]


#111092

FromRustom Mody <rustompmody@gmail.com>
Date2016-07-04 20:37 -0700
Message-ID<a6456c22-8346-4480-b9a2-ff54265fc91e@googlegroups.com>
In reply to#111090
On Tuesday, July 5, 2016 at 8:50:57 AM UTC+5:30, Steven D'Aprano wrote:
> I got this in Python 3.6:
> 
> 
> py> class A:
> ...     var = 999
> ...     print(var)  # succeeds
> ...     class B:
> ...         x = var
> ...
> 999
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 3, in A
>   File "<stdin>", line 4, in B
> NameError: name 'var' is not defined
> 
> 
> I expected that `var` would be available during the construction of B, just
> as it was available inside A, but not to methods inside B. Obviously my
> expectations are invalid. Can anyone explain the actual behaviour?
> 

Heh!
Nice to see you confused by python's ‘concave’ LEGB rule
One of those thing I never get used to…

[toc] | [prev] | [next] | [standalone]


#111093

FromPaul Rubin <no.email@nospam.invalid>
Date2016-07-04 20:42 -0700
Message-ID<87y45gg387.fsf@jester.gateway.pace.com>
In reply to#111090
Steven D'Aprano <steve@pearwood.info> writes:
> ...     class B:
> ...         x = var

x = A.var

[toc] | [prev] | [next] | [standalone]


#111097

FromIan Kelly <ian.g.kelly@gmail.com>
Date2016-07-04 22:37 -0600
Message-ID<mailman.84.1467693483.2295.python-list@python.org>
In reply to#111093
On Mon, Jul 4, 2016 at 9:42 PM, Paul Rubin <no.email@nospam.invalid> wrote:
> Steven D'Aprano <steve@pearwood.info> writes:
>> ...     class B:
>> ...         x = var
>
> x = A.var

Nope. A doesn't exist yet at this point.

[toc] | [prev] | [next] | [standalone]


#111098

FromIan Kelly <ian.g.kelly@gmail.com>
Date2016-07-04 22:41 -0600
Message-ID<mailman.85.1467693723.2295.python-list@python.org>
In reply to#111090
On Mon, Jul 4, 2016 at 9:20 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> I got this in Python 3.6:
>
>
> py> class A:
> ...     var = 999
> ...     print(var)  # succeeds
> ...     class B:
> ...         x = var
> ...
> 999
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "<stdin>", line 3, in A
>   File "<stdin>", line 4, in B
> NameError: name 'var' is not defined
>
>
> I expected that `var` would be available during the construction of B, just
> as it was available inside A, but not to methods inside B. Obviously my
> expectations are invalid. Can anyone explain the actual behaviour?

Class definitions don't create closures like functions do. When Python
executes a class definition, the metaclass creates a dict, and then
the interpreter execs the class body using that dict as the locals.
The body of class A has one locals dict, and the body of class B has a
completely separate locals dict. The only way to share variables
between them (prior to the class objects actually being constructed)
is via globals.

[toc] | [prev] | [next] | [standalone]


#111101

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2016-07-05 15:40 +1000
Message-ID<577b4848$0$2763$c3e8da3$76491128@news.astraweb.com>
In reply to#111098
On Tuesday 05 July 2016 14:41, Ian Kelly wrote:

> Class definitions don't create closures like functions do. When Python
> executes a class definition, the metaclass creates a dict, and then
> the interpreter execs the class body using that dict as the locals.
> The body of class A has one locals dict, and the body of class B has a
> completely separate locals dict. The only way to share variables
> between them (prior to the class objects actually being constructed)
> is via globals.


So, like nested functions in Python before "from __future__ import 
nested_scopes".


Okay, that's reasonable.



-- 
Steve

[toc] | [prev] | [next] | [standalone]


#111124

Fromeryk sun <eryksun@gmail.com>
Date2016-07-05 12:45 +0000
Message-ID<mailman.98.1467722789.2295.python-list@python.org>
In reply to#111101
On Tue, Jul 5, 2016 at 5:40 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> On Tuesday 05 July 2016 14:41, Ian Kelly wrote:
>
>> Class definitions don't create closures like functions do. When Python
>> executes a class definition, the metaclass creates a dict, and then
>> the interpreter execs the class body using that dict as the locals.
>> The body of class A has one locals dict, and the body of class B has a
>> completely separate locals dict. The only way to share variables
>> between them (prior to the class objects actually being constructed)
>> is via globals.
>
>
> So, like nested functions in Python before "from __future__ import
> nested_scopes".

In Python 3.4+, the code for a class body does participate in
closures. The CPython compiler implements this using the
LOAD_CLASSDEREF instruction. However, classes don't create closures
and default to storing to the locals dict (as class attributes),
unless a name is declared global or nonlocal. Obviously writing to a
global or nonlocal won't create a class attribute. For example:

    def f():
        y = 0
        class C:
            global x
            nonlocal y
            x = 1
            y = 2
            z = 3
        return types.SimpleNamespace(**locals())

    >>> ns = f()
    >>> x
    1
    >>> ns.y
    2
    >>> ns.C.z
    3
    >>> sorted(vars(ns.C))
    ['__dict__', '__doc__', '__module__', '__weakref__', 'z']

[toc] | [prev] | [next] | [standalone]


#111099

FromIan Kelly <ian.g.kelly@gmail.com>
Date2016-07-04 22:43 -0600
Message-ID<mailman.86.1467693868.2295.python-list@python.org>
In reply to#111090
On Mon, Jul 4, 2016 at 10:41 PM, Ian Kelly <ian.g.kelly@gmail.com> wrote:
> On Mon, Jul 4, 2016 at 9:20 PM, Steven D'Aprano <steve@pearwood.info> wrote:
>> I got this in Python 3.6:
>>
>>
>> py> class A:
>> ...     var = 999
>> ...     print(var)  # succeeds
>> ...     class B:
>> ...         x = var
>> ...
>> 999
>> Traceback (most recent call last):
>>   File "<stdin>", line 1, in <module>
>>   File "<stdin>", line 3, in A
>>   File "<stdin>", line 4, in B
>> NameError: name 'var' is not defined
>>
>>
>> I expected that `var` would be available during the construction of B, just
>> as it was available inside A, but not to methods inside B. Obviously my
>> expectations are invalid. Can anyone explain the actual behaviour?
>
> Class definitions don't create closures like functions do. When Python
> executes a class definition, the metaclass creates a dict, and then
> the interpreter execs the class body using that dict as the locals.
> The body of class A has one locals dict, and the body of class B has a
> completely separate locals dict. The only way to share variables
> between them (prior to the class objects actually being constructed)
> is via globals.

Or I suppose one could write a metaclass that does something fancy
when creating the dicts.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web