for x in... x remains global

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Antoine De Groote

    #1

    for x in... x remains global

    for x in range(3): pass

    After this statement is executed x is global variable. This seems very
    unnatural to me and caused me 3 three days of debugging because I was
    unintentionally using x further down in my program (typo). I would have
    thought that variables like this are local to the for block.

    Is there a reason this is not the case? Maybe there are PEPs or
    something else about the matter that you can point me to?

    Regards,
    antoine
  • Diez B. Roggisch

    #2
    Re: for x in... x remains global

    Antoine De Groote wrote:
    for x in range(3): pass
    >
    After this statement is executed x is global variable. This seems very
    unnatural to me and caused me 3 three days of debugging because I was
    unintentionally using x further down in my program (typo). I would have
    thought that variables like this are local to the for block.
    >
    Is there a reason this is not the case? Maybe there are PEPs or
    something else about the matter that you can point me to?
    It's an somewhat unfortunate fact that loop variables leak to the outer
    scope. List-comps as well, btw.

    In

    This PEP introduces generator expressions as a high performance, memory efficient generalization of list comprehensions PEP 202 and generators PEP 255.


    it says that this will be remedied in Py3K

    """
    List comprehensions also "leak" their loop variable into the surrounding
    scope. This will also change in Python 3.0, so that the semantic definition
    of a list comprehension in Python 3.0 will be equivalent to list(<generator
    expression>). Python 2.4 and beyond should issue a deprecation warning if a
    list comprehension's loop variable has the same name as a variable used in
    the immediately surrounding scope.
    """

    And while I can't make an authorative statement about this, I can imagine
    that it won't be fixed anywhere in python2.X, as code like this is
    certainly to be found:

    for x in some_xes:
    if condition(x):
    break

    print x


    Diez

    Comment

    • Duncan Booth

      #3
      Re: for x in... x remains global

      Antoine De Groote <antoine@vo.luw rote:
      for x in range(3): pass
      >
      After this statement is executed x is global variable. This seems very
      unnatural to me and caused me 3 three days of debugging because I was
      unintentionally using x further down in my program (typo). I would have
      thought that variables like this are local to the for block.
      Blocks in Python never create new scopes. You have global variables for
      each module and one set of local variables for each function. There is a
      minor exception in that the control variables in generator expressions are
      in a separate scope, but variables are never local to a block.
      Is there a reason this is not the case? Maybe there are PEPs or
      something else about the matter that you can point me to?
      One good reason is that sometimes you want to use the loop variable after
      the end of the loop:

      for x in somesequence:
      if somecondition(x ):
      break
      else:
      raise NotFoundError
      print "found", x

      Try to write lots of small functions and then you can keep the scope of
      variables suitably small.

      Comment

      • Ben Finney

        #4
        Re: for x in... x remains global

        Antoine De Groote <antoine@vo.luw rites:
        for x in range(3): pass
        >
        After this statement is executed x is global variable.
        Not exactly. The name 'x' is bound at the scope of the 'for'
        statement, and remains bound after the 'for' statement stops, just as
        it would be if it was bound in any other statement.
        This seems very unnatural to me and caused me 3 three days of
        debugging because I was unintentionally using x further down in my
        program (typo).
        This is, when used intentionally, one of the main useful features of
        this behaviour: to determine where an iteration stopped by using the
        value bound to the name ('x' in this case) after the iteration
        statement.
        I would have thought that variables like this are local to the for
        block.
        They're bound at the scope of the 'for' statement. They're available
        inside the suite of that statement.
        Is there a reason this is not the case? Maybe there are PEPs or
        something else about the matter that you can point me to?
        This message addresses it:

        <URL:http://mail.python.org/pipermail/python-dev/2006-April/064624.html>

        A search for the separate terms "python iteration variable scope" will
        turn up more.

        --
        \ "The best way to get information on Usenet is not to ask a |
        `\ question, but to post the wrong information." -- Aahz |
        _o__) |
        Ben Finney

        Comment

        • skip@pobox.com

          #5
          Re: for x in... x remains global


          DiezIt's an somewhat unfortunate fact that loop variables leak to the
          Diezouter scope. List-comps as well, btw.

          It's unfortunate that loop variables leak from list comprehensions (they
          don't leak in genexps). It's by design in for loops though. Consider:

          for i in range(10):
          if i*i == 9:
          break
          print i

          In this silly example, the loop index is the useful value of the
          computation. You could assign to a different variable, though that would be
          slightly ugly:

          for i in range(10:
          j = i
          if j*j == 9:
          break
          print j

          Skip

          Comment

          Working...