On Mon, Apr 09, 2001 at 12:38:55AM -0700, Kirby Urner wrote:
I'm unclear on how scoping is handled in Python scripts.
===== ## parameters = name print "Hello %s" % name return printed =====
works as a script but:
===== ## parameters = name print function() print "Hello %s" % name return printed
def function(): return "Goodbye" =====
does not -- because 'function' is not found. However:
===== ## parameters = name def function(): return "Goodbye"
# Main print function() print "Hello %s" % name return printed
=====
is OK, as 'function' is defined above the main stuff. However I can't get 'function' to see another function e.g.:
===== ## parameters = name
def add2(a): return a+2
def function(): n = add2(3) return "Goodbye"
# Main print function() print "Hello %s" % name return printed
=====
'add2' won't be found, I guess because it's "two levels deep" (??). However, it'll work if I make 'add2' internal to 'function'...
===== ## parameters = name
def function(): def add2(a): return a+2
n = add2(3) return "Goodbye"
# Main print function() print "Hello %s" % name return printed
=====
So what are the rules here? I'm used to Python modules with one shared scope for all top-level function defs, no matter what level they're called from. Why can't 'add2' be defined at the same level as 'function' (above), or is there syntax to make this work (I've been trying stuff like script.add2(3) or context.add2(3) but that doesn't help).
This sounds like your typical Python nested namespaces problem, which is solved in Python 2.1 in an optional __future__ module, and standard fare in Python 2.2. A python Script is a function in itself, so it's namespace isn't the global module space you are expecting. Normally, you would indeed expect function() and add2() to be visible throughout your script, as they have been defined at the module level. However, a Python Script isn't defined at the module level; it is defined as a function within a module. you should mentally indent the whole code and add 'function <id of PS here>(<paramater list here>):' before it. So, here only the local scole rules apply: only names that have been declared before you are visible, and you get a new local namespace when calling a function. Python 2.1 solves this problem by introducing nested scopes. I assume that because Zope 2.4 will probably require Python 2.1, the problem will disappear (if Python Scripts do a 'from __future__ import nested_scopes). For now however, you'll have to live with this problem, or see if you can manipulate globals() in Python Scripts (not sure if you can). A good overview of what nested scopes are about, see: http://www.amk.ca/python/2.1/index.html#SECTION000300000000000000000 The original PEP is at: http://python.sourceforge.net/peps/pep-0227.html And finally, the official documentation can be found at: http://python.sourceforge.net/devel-docs/ref/nested-scopes.html -- Martijn Pieters | Software Engineer mailto:mj@digicool.com | Digital Creations http://www.digicool.com/ | Creators of Zope http://www.zope.org/ ---------------------------------------------