[Python-Dev] nested scopes confusion (original) (raw)

Jeremy Hylton jeremy@zope.com
Tue, 4 Dec 2001 14:57:23 -0500 (EST)


def functions(): result = [] for i in range(10): def mth(*args): return i result.append(mth) i = 25 return result

for mth in functions(): print mth()

"TH" == Thomas Heller <thomas.heller@ion-tof.com> writes:

TH> Reading PEP227, I can (barely) understand why it behaves this TH> way.

It behaves this way because the reference to i in mth() uses the binding for i introduced in functions(). The important point here is that the binding is used, but i can be bound to different values at different times. The function mth() sees the value that i is bound to when it is called. In your example, mth() isn't called until after the loop finishes executing.

TH> How do I achieve the desired effect? Note that the default TH> argument trick (def mth(i=i): ...) does not work because *args TH> is present.

All sorts of ways, I imagine. You could use a class:

class MthClass:

  def __init__(self, val):
  self.val = val

  def mth(self, *args):
  return self.val

This version is probably immediately obvious to the reader.

You could add an extra layer of functions, but this looks like a pretty obscure use of nested scopes to me.

def functions(): ... result = [] ... for i in range(10): ... def wrap(i): ... def mth(*args): ... return i ... return mth ... result.append(wrap(i)) ... i = 25 ... return result ... l = functions() l0 0 l1 1

Jeremy