Need help with Python scoping rules
apt.shansen at gmail.com
Tue Aug 25 22:16:24 CEST 2009
> But http://docs.python.org/tutorial/classes.html says, in Section 9.3 "A
> First Look at Classes":
> When a class definition is entered, a new namespace is created,
> and used as the local scope — thus, all assignments to local variables
> go into this new namespace. In particular, function definitions bind
> the name of the new function here.
> (BTW, Diez, your toy example is another demonstration that there *is* a
> class-scope-lookup: the "def" statement binds the name "fact" in the class
> scope, and the assignment statement looks up the name "fact" in that scope.)
This sounds like a fundamental confusion -- a namespace is not equivalent to
a scope, really, I think.
The def statement creates a function object, and assigns it to the given
name, in its /local scope/ which is the class's namespace -- but that is not
a new scope. Its just, during class creation, the local scope.
When you enter a class definition, a new namespace is created, and that is
used as the local scope during the class's definition. Under "class Foo",
the local scope is this class's namespace-- and the global scope is the
module's namespace. Any lookup operation checks first in the local scope,
then in the global scope...
When the "def fact(...)" is executed (note that class bodies are executed on
load, function bodies aren't), a new namespace is created as well-- the
function's namespace-- and its used as the local scope. During execution of
the code, it looks up in the local scope first-- and then it looks up in the
global scope if it doesn't find anything. There /is/ no
class-lookup-scope... but there IS a class namespace.
There's just those two scopes: but the namespace bound to those scopes
changes as you enter different parts of the code.
For a long time that's all there was, just the local and global scope: to
access any other namespace required you to explicitly address it. The class
namespace remains accessible only via explicit addressing, but PEP 227 in
Python 2.1/2.2 introduced static nested scopes. But that applies only to
enclosing functions: embedding one function into another.
You can only call recursive functions if the function is able to refer to
itself according to the same lookup rules: is the function's name in the
local scope? No it's not... is it in the global scope? No? Then it can't
call itself recursively... well, unless its a method, and it addresses
itself specifically-- with "self.".
The OP's probably is that during the execution of the class body, the class
doesn't exist... so the 'def fact' -can't- use Classname.fact to address
itself explicitly, and within fact the locals don't contain a reference to
the function itself, and its globals don't either. You just can't do that.
The right way, IMHO, is to move 'fact' up and out of the class into a _fact
global variable. Alternatively, you can use a metaclass.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Python-list