Nested function scope problem

danielx danielwong at berkeley.edu
Wed Jul 26 21:50:46 EDT 2006


Bruno Desthuilliers wrote:
> Gerhard Fiedler wrote:
> > On 2006-07-25 04:06:24, Steve Holden wrote:
> >
> >
> >>Dennis Lee Bieber wrote:
> >>
> >>>On Mon, 24 Jul 2006 17:35:50 -0300, Gerhard Fiedler <gelists at gmail.com>
> >>>declaimed the following in comp.lang.python:
> >>>
> >>>
> >>>>It is surprising in the sense that binding seems not to be necessary
> >>>>for read access.
> >>>
> >>It does, I would agree, seem a little counter-intuitive that assignment
> >>(or binding) forces the name to be considered local. That's just one of
> >>Python's features.
> >
> >
> > Ok... I can live with that, and thanks for the confirmation that it's not
> > only me to feel that this is somewhat surprising :)
>
> Since Python has no "local variable declaration", there must be a rule
> to distinguish local names from names living in the enclosing
> namespaces. The rule is: unless previously declared 'global' (ie
> module-level) with the appropriate statement, any name bound in the
> local namespace is local. If declared 'global', it has to exist in the
> global namespace.
>
> This was much more simple to understand when we didn't have nested
> functions - we mostly had global and local scope. Fact is that we now
> have nested functions, but still no statement equivalent to 'global' for
> parent namespaces - with the result that we cannot actually rebind
> parent's namespace names from within a nested function. But we are still
> free to modify any mutable object we can access, so the usual workaround
>   for immutable objects is to wrap them in a mutable container (list,
> dict, etc):
>
> def outer():
>   def _inner():
>      outer_var[0] = 'dead'
>
>   outer_var = ['parrot']
>   print "before, outer_var = %s" % outer_var
>   _inner()
>   print "after, outer_var = %s" % outer_var
>
> and before you say it: yes, it's a dirty hack.
>
>
> > Surprising for me are actually two things: 1- the fact itself, and 2- that
> > term "binding", and that whatever it means > (I'll have to read more on that,
> > now that I know the term)
>
> a "binding" is the association of a name and a reference to an object in
> a given namespace. It's different from the common notion of "variable",
> which is usually a symbolic name for a memory address storing a value
> (like a pointer to an object's address).

Wait, I'm not sure I see the difference. Isn't "reference" ~ "C
pointer". Are you saying Python variables don't hold references to
"actual" Python objects? That idea has been working well for me so far.

>
> is different for read-only and read/write access.
>
> What makes the difference is that binding a name to an object in a
> namespace creates the name in this namespace (unless the name as been
> declared global, cf above). With the result that, the name existing in
> the local namespace, it won't be looked up in enclosing namespaces.
>
>
> > Neither the Post-It note metaphor nor the pointer explanation address that.
> > Using the Post-It note metaphor, I'm asking myself why the label doesn't
> > get attached to a different box when reading,
>
> The normal lookup rule for names is local namespace then enclosing
> namespaces until top-level (module, aka 'global'), then builtins. Else,
> you would have to declare as global any "module / function / whatever"
> name in each and every function.
>
> > but only when writing.
>
> cf above and below.
>
> >("Just
> > one of Python's features", I know :)  Same thing with the pointer
> > explanation: AFAIK, no language that uses pointers explicitly does
> > something similar (that is, the storage the pointer points to is different
> > depending on whether the pointer gets used for writing and reading, or only
> > for reading).
>
> In most languages, you have to explicitly declare local names one way or
> another. Python takes the opposite route : you have to explicitly
> declare global names. Since you don't declare local names, binding
> creates the name if it doesn't already exists in the local namespace.
>
>
> HTH
> --
> bruno desthuilliers
> python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
> p in 'onurb at xiludom.gro'.split('@')])"




More information about the Python-list mailing list