Namespaces in functions vs classes

Chris Rebert clp2 at rebertia.com
Sun Apr 17 15:56:23 EDT 2011


On Sun, Apr 17, 2011 at 12:30 PM, Gerald Britton
<gerald.britton at 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.

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



More information about the Python-list mailing list