why is this not working? (nested scope question)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • biner.sebastien@ouranos.ca

    #1

    why is this not working? (nested scope question)

    I have a problem understanding the scope of variable in nested
    function. I think I got it nailed to the following example copied from
    Learning Python 2nd edition page 205. Here is the code.

    def f1() :
    x=88
    f2()
    def f2() :
    print 'x=',x
    f1()

    that returns an error saying that "NameError: global name 'x' is not
    defined". I expected f2 to "see" the value of x defined in f1 since it
    is nested at runtime. My reading of the book comforted me in this.

    What am I missing? Shouldn't the E of the LEGB rule take care of that.
    BTW, I am running this on python 2.3.

    Thanks.

    Sébastien.

  • Peter Otten

    #2
    Re: why is this not working? (nested scope question)

    biner.sebastien @ouranos.ca wrote:
    I have a problem understanding the scope of variable in nested
    function. I think I got it nailed to the following example copied from
    Learning Python 2nd edition page 205. Here is the code.
    >
    def f1() :
    x=88
    f2()
    def f2() :
    print 'x=',x
    f1()
    >
    that returns an error saying that "NameError: global name 'x' is not
    defined". I expected f2 to "see" the value of x defined in f1 since it
    is nested at runtime. My reading of the book comforted me in this.
    >
    What am I missing? Shouldn't the E of the LEGB rule take care of that.
    BTW, I am running this on python 2.3.
    For f1 to be seen as the enclosing scope of f2 f2 has to be /defined/ in f1:
    >>def f1():
    .... x = 88
    .... def f2():
    .... print "x =", x
    .... f2()
    ....
    >>f1()
    x = 88

    Just /calling/ a function inside another does not give the inner one access
    to variables that are visible in the outer.

    Peter

    Comment

    • Tim Chase

      #3
      Re: why is this not working? (nested scope question)

      biner.sebastien @ouranos.ca wrote:
      I have a problem understanding the scope of variable in nested
      function. I think I got it nailed to the following example copied from
      Learning Python 2nd edition page 205. Here is the code.
      >
      def f1() :
      x=88
      f2()
      def f2() :
      print 'x=',x
      f1()
      >
      that returns an error saying that "NameError: global name 'x' is not
      defined". I expected f2 to "see" the value of x defined in f1 since it
      is nested at runtime. My reading of the book comforted me in this.
      >
      What am I missing? Shouldn't the E of the LEGB rule take care of that.
      There's a subtle difference between what you have:
      >>def f1() :
      .... x=88
      .... f2()
      >>def f2() :
      .... print 'x=',x
      >>f1()
      [traceback]

      and
      >>def f1():
      .... x = 88
      .... def f2():
      .... print 'x =',x
      .... f2()
      ....
      >>f1()
      x = 88

      The E in LEGB, as far as I understand it, involves to functions
      whose *definitions* are nested within another function...not
      those functions *called* within another function. Craziness
      ensues with the next example:
      >>def f1():
      .... x = 99
      .... def f2():
      .... print 'x =',x
      .... x = 77
      .... f2()
      ....
      >>f1()
      x = 77


      It makes sense...you just have to understand what it's doing. :)

      -tkc



      Comment

      • bryanjugglercryptographer@yahoo.com

        #4
        Re: why is this not working? (nested scope question)


        biner.sebastien @ouranos.ca wrote:
        [...]
        def f1() :
        x=88
        f2()
        def f2() :
        print 'x=',x
        f1()
        >
        that returns an error saying that "NameError: global name 'x' is not
        defined". I expected f2 to "see" the value of x defined in f1 since it
        is nested at runtime.
        Ah, no, Python uses "static scoping". Google the term for more.


        --
        --Bryan

        Comment

        • biner.sebastien@ouranos.ca

          #5
          Re: why is this not working? (nested scope question)


          Thanks for the answers.

          I do understand (and verified) that if I define f2 within f1, it works
          as expected. But in the "learning pyton 2nd edition" at page 205 it is
          said that "Programs are much simpler if you do not nest defs within
          defs" (juste before the code mentioned in my initial message).

          In a way, I though the local variables of f1 would in a way add to the
          global variable of f2 (because f1 called f2) and that f2 would look in
          the global variables when it could not find a variable locally
          (following the LEGB rule).

          Still the code I put is presented in the book and it does not work for
          me. I googled for errata regarding that code but did not find any.

          Sébastien.

          Comment

          • John Salerno

            #6
            Re: why is this not working? (nested scope question)

            biner.sebastien @ouranos.ca wrote:
            I do understand (and verified) that if I define f2 within f1, it works
            as expected. But in the "learning pyton 2nd edition" at page 205 it is
            said that "Programs are much simpler if you do not nest defs within
            defs" (juste before the code mentioned in my initial message).
            Actually, the code in the book is:

            def f1():
            x = 88
            f2(x)

            def f2(x):
            print x

            f1()

            which makes all the difference in the world. Not to mention that this
            particular section of the book is giving an example of how to write the
            code *without* using nested functions.

            Comment

            • biner.sebastien@ouranos.ca

              #7
              Re: why is this not working? (nested scope question)

              Actually, the code in the book is:
              >
              def f1():
              x = 88
              f2(x)
              >
              def f2(x):
              print x
              >
              f1()
              >
              which makes all the difference in the world. Not to mention that this
              particular section of the book is giving an example of how to write the
              code *without* using nested functions.
              Ouch! You got me there, I did not copy the code properly. Now I feel
              stupid. Thanks for the enlightment.

              I think I am starting to get it.

              Sébastien.

              Comment

              • John Salerno

                #8
                Re: why is this not working? (nested scope question)

                biner.sebastien @ouranos.ca wrote:
                Ouch! You got me there, I did not copy the code properly. Now I feel
                stupid. Thanks for the enlightment.
                >
                I think I am starting to get it.
                P.S. The point of the example was to show how nesting isn't necessary
                much of the time. The authors wanted to show that it is okay to write a
                call to f2 before f2 is even defined, as long as f2 is defined before
                that call is actually executed, i.e. when f1() is called. Keeping the
                two functions separate is cleaner than nesting, and passing parameters
                is how you get around the local scope issue.

                Comment

                Working...