Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #111090 > unrolled thread
| Started by | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| First post | 2016-07-05 13:20 +1000 |
| Last post | 2016-07-04 22:43 -0600 |
| Articles | 8 — 6 participants |
Back to article view | Back to comp.lang.python
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
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-07-05 13:20 +1000 |
| Subject | Nested 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]
| From | Rustom Mody <rustompmody@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Paul Rubin <no.email@nospam.invalid> |
|---|---|
| Date | 2016-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2016-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]
| From | eryk sun <eryksun@gmail.com> |
|---|---|
| Date | 2016-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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2016-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