So the way I envision it is that *in the absence of a nonlocal or global
declaration in the containing scope*, := inside a comprehension or genexpr
causes the compiler to assign to a local in the containing scope, which is
elevated to a cell (if it isn't already). If there is an explicit nonlocal
or global declaration in the containing scope, that is honored.

Examples:

  # Simplest case, neither nonlocal nor global declaration
  def foo():
      [p := q for q in range(10)]  # Creates foo-local variable p
      print(p)  # Prints 9

  # There's a nonlocal declaration
  def bar():
      p = 42  # Needed to determine its scope
      def inner():
          nonlocal p
          [p := q for q in range(10)]  # Assigns to p in bar's scope
      inner()
      print(p)  # Prints 9

  # There's a global declaration
  def baz():
      global p
      [p := q for q in range(10)]
  baz()
  print(p)  # Prints 9

All these would work the same way if you wrote list(p := q for q in
range(10)) instead of the comprehension.

We should probably define what happens when you write [p := p for p in
range(10)]. I propose that this overwrites the loop control variable rather
than creating a second p in the containing scope -- either way it's
probably a typo anyway.

:= outside a comprehension/genexpr is treated just like any other
assignment (other than in-place assignment), i.e. it creates a local unless
a nonlocal or global declaration exists.

-- 
--Guido van Rossum (python.org/~guido)
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to