[Python-ideas] Jump to function as an an alternative to call function
Chris Barker
chris.barker at noaa.gov
Thu Aug 16 15:32:54 EDT 2018
On Thu, Aug 16, 2018 at 10:33 AM, Jonathan Fine <jfine2358 at gmail.com> wrote:
> >> there
> >> are times where I have really wanted to access the caller's environment,
> >> not the environment where my function was defined.
>
> > what am I missing? can't you get that by passing locals() in to a
> function?
>
> I think this will fail when values are changed. According to
> https://docs.python.org/3/library/functions.html#locals
> > The contents of this dictionary should not be modified; changes may not
> affect the values of local and free variables used by the interpreter.
>
and:
"""
locals()
Update and return a dictionary representing the current local symbol table.
Free variables are returned by locals() when it is called in function
blocks, but not in class blocks.
"""
it a dictionary *representing* the current local symbol table, so not the
actual symbol table -- which surprised me, I thought that is was -- and
sometimes it appears to be -- see later example:
> To finish, here's an interactive example of changing the value of
locals().
>
> >>> def f(a=1): loc = locals(); yield loc; yield a
> >>> it = f()
> >>> ctx = next(it)
> >>> ctx
> {'a': 1} ## This surprised me.
>
me too I would have thought "loc" would be in there.
> >>> def f(a=1): loc = locals(); yield locals(); yield a
> >>> it = f()
> >>> ctx = next(it)
> >>> ctx
> {'a': 1, 'loc': {...}}
>
now "loc is there"
> >>> ctx['a'] = 3
> >>> ctx['loc']['a'] = 5
> >>> next(it) ## Is it 1 or 3 or 5?
> 1 ## The value of 'a' hasn't changed.
hmm -- made me think that generators are doing something different here --
and indeed they are. If you use regular functions:
In [30]: def local_modifying(loc):
...: """
...: adds a "fred" key to the dict passed in
...: """
...: print("locals passed in:", loc)
...: loc['fred'] = 5
...: print("locals after adding", loc)
...:
In [31]: def test_locals():
...: """
...: a simple local namespace to use
...: """
...: a = 1
...: b = 2
...: local_modifying(locals())
...: # does "fred" exist?
...: print(locals())
...: # and we can access it the usual way
...: print("fred:", fred)
...:
In [32]: test_locals()
locals passed in: {'b': 2, 'a': 1}
locals after adding {'b': 2, 'a': 1, 'fred': 5}
{'b': 2, 'a': 1, 'fred': 5}
fred: 5
It seems you CAN modify the locals dict passed in, and the change will show
up in the enclosing scope.
But it sounds like that is not guaranteed by the language.
-CHB
--
Christopher Barker, Ph.D.
Oceanographer
Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
Chris.Barker at noaa.gov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180816/5cf5c682/attachment.html>
More information about the Python-ideas
mailing list