On Apr 17, 8:56 pm, Chris Rebert <c...@rebertia.com> wrote:
> On Sun, Apr 17, 2011 at 12:30 PM, Gerald Britton
>
>
>
>
>
>
>
>
>
> <gerald.brit...@gmail.com> wrote:
> > I apologize if this has been answered before or if it is easy to find
> > in the docs. (I couldn't find it but might have missed it)
>
> > I'm trying to understand the differences between namespaces in class
> > definitions vs. function definitions.  Consider this function:
>
> >>>> def a():
> > ...     foo = 'foo'
> > ...     def g(x):
> > ...         return foo
> > ...     print g(1)
> > ...
> >>>> a()
> > foo
>
> > Now, I replace the first "def" with "class":
>
> >>>> class a():
> > ...     foo = 'foo'
> > ...     def g(x):
> > ...         return foo
> > ...     print g(1)
> > ...
> > Traceback (most recent call last):
> >  File "<stdin>", line 1, in <module>
> >  File "<stdin>", line 5, in a
> >  File "<stdin>", line 4, in g
> > NameError: global name 'foo' is not defined
>
> > So, the variable "foo" is not available inside the function inside
> > class as it is inside the (inner) function.  I figured this was just
> > because the class was still being defined, so I tried this:
>
> >>>> class a():
> > ...     foo = 'foo'
> > ...     def g(x):
> > ...         return foo
> > ...
> >>>> x = a()
> >>>> x.g()
> > Traceback (most recent call last):
> >  File "<stdin>", line 1, in <module>
> >  File "<stdin>", line 4, in g
> > NameError: global name 'foo' is not defined
>
> > which still fails.  I had expected that "foo" would be available
> > within the namespace of the object instance.  I was wrong.  For my
> > final attempt, I add the prefix "a." to my use of "foo"
>
> >>>> class a():
> > ...     foo = 'foo'
> > ...     def g(x):
> > ...         return a.foo
> > ...
> >>>> x = a()
> >>>> x.g()
> > 'foo'
>
> > So, this works and I can use it.  However,  I would like a deeper
> > understanding of why I cannot use "foo" as an unqualified variable
> > inside the method in the class.  If Python allowed such a thing, what
> > problems would that cause?
>
> Class-level scope is simply never consulted when looking up
> unqualified names in methods. When looking up such name from within a
> method, the following scopes are consulted, in order (ignoring some
> subtleties):
> 1. Local variables
> 2. Variables in nested functions
> 3. Global variables
> 4. Built-ins
>
> For "workarounds" for this, 
> see:http://mail.python.org/pipermail/python-list/2009-December/1228354.html
>
> As to why Python works this way, I'm not sure. However, one could
> cogently argue that this requires you to be more explicit about what
> the scope is of the name you're referring to; which set of semantics
> you desire in the face of inheritance, monkey-patching, and instance
> variable shadowing makes this trickier than you might otherwise think.

I don't know but I suspect that the reason is one of optimisation.
Functions know what the locally defined names are so when it is
compiled it uses the opcode that loads from the local variable
namespace. Functions also know what their closure is (that is, the
locally defined names of enclosing functions) and can do an
appropriate thing in that case. If a name does not fall into either of
those two categories it is loaded with the LOAD_GLOBAL opcode. The
result of all this is that functions find the correct namespace very
quickly.

If variables in class scope were to be accessible unqualified from
within a method either loading of global names (a VERY common
operation) would be made notably slower, or the class namespace would
have to be immutable (which I think we can agree would be
undesirable), or possibly other, more complicated tradeoffs I haven't
considered.

This is all just guesswork. As a suitable proxy for the class (i.e. an
instance thereof) is available within the local scope of all methods,
getting those class variables is quite straightforward really.
Personally I find qualifying the scope of variables that aren't
globals or builtins to be a restriction that leads to better, clearer
code. :-)

> Cheers,
> Chris
> --http://blog.rebertia.com

-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to