Declare a variable global

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • yinglcs@gmail.com

    #1

    Declare a variable global

    Hi,

    I have the following code:

    colorIndex = 0;

    def test():
    print colorIndex;

    This won't work. But it works if i do this:

    colorIndex = 0;

    def test():
    global colorIndex;
    print colorIndex;

    My question is why do I have to explicit declaring 'global' for
    'colorIndex'? Can't python automatically looks in the global scope
    when i access 'colorIndex' in my function 'test()'?

    Thank you.

  • yinglcs@gmail.com

    #2
    Re: Declare a variable global

    On Feb 19, 11:09 am, Jean-Paul Calderone <exar...@divmod .comwrote:
    On 19 Feb 2007 09:04:19 -0800, "ying...@gmail. com" <ying...@gmail. comwrote:
    >
    Hi,
    >
    I have the following code:
    >
    colorIndex = 0;
    >
    def test():
    print colorIndex;
    >
    This won't work.
    >
    Are you sure?
    >
    exarkun@charm:~ $ cat foo.py
    colorIndex = 0
    >
    def test():
    print colorIndex
    >
    test()
    exarkun@charm:~ $ python foo.py
    0
    exarkun@charm:~ $
    >
    The global keyword lets you rebind a variable from the module scope. It
    doesn't have much to do with accessing the current value of a variable.
    >
    Jean-Paul
    Thanks. Then I don't understand why I get this error in line 98:

    Traceback (most recent call last):
    File "./gensvg.py", line 109, in ?
    outdata, minX, minY, maxX, maxY = getText(data);
    File "./gensvg.py", line 98, in getText
    print colorIndex;
    UnboundLocalErr or: local variable 'colorIndex' referenced before
    assignment


    Here is my complete script:
    #!/usr/bin/python

    import re
    import sys
    import time
    import os
    import shutil

    colors = ["#FF0000", "#00FF00", "#0000FF",
    "#FFFF00" ,"#FFA500" ,"#DA70D6"]
    colorIndex = 0

    def getText( intputstr):
    rc = ""

    maxX = 0;
    maxY = 0;
    minX = 10000000;
    minY = 10000000;


    for str in intputstr:

    print str;

    if str != "":
    pattern = "x:(\d+) y:(\d+) w:(\d+) h:(\d+) (.*)"

    match = re.findall(patt ern, str)

    if match:
    x, y, width, height, area = match[0]

    colorIndex = colorIndex + 1

    rc = rc + "<rect x=\"%(x)s\" y=\"%(y)s\" width=\"%
    (width)s\" height=\"%(heig ht)s\" " % locals()

    rc = rc + "fill=\"%s\ " stroke=\"#00000 0\" stroke-width=
    \"1px\" fill-opacity=\".5\" />\n" % colors[colorIndex % len(colors)]

    _x = int(x)
    _y = int(y)
    _width = int(width)
    _height = int(height)

    minX = min(minX, _x);
    minY = min(minY, _y);

    maxX = max(maxX, _x+ _width);
    maxY = max(maxY, _y+_height);



    else:
    pattern = "\((\d+),(\d+)\ )\((\d+),(\d+)\ )(.*)"

    match = re.findall(patt ern, str)

    if match:
    x1, y1, x2, y2, ignore = match[0]

    rc = rc + "<line x1=\"%(x1)s\" y1=\"%(y1)s\" x2=\"%
    (x2)s\" y2=\"%(y2)s\" style=\"stroke: rgb(99,99,99);s troke-width:2\" /
    >" % locals()
    rc = rc + "\n"

    _x1 = int(x1)
    _y1 = int(y1)
    _x2 = int(x2)
    _y2 = int(y2)

    minX = min(_x1, _x2);
    minY = min(_y1, _y2);

    maxX = max(_x1, _x2);
    maxY = max(_y1, _y2);

    print colorIndex;

    print "match 2!"


    return rc, minX, minY, maxX, maxY;

    fileName = sys.argv[1]

    inputFile = open(fileName, 'r')
    data = inputFile.readl ines();
    outdata, minX, minY, maxX, maxY = getText(data);

    print minX, minY, maxX, maxY

    outputFile = open(fileName + '.svg', 'w')

    print >outputFile, "<svg xmlns=\"http://www.w3.org/2000/svg\"
    xmlns:xlink=\"h ttp://www.w3.org/1999/xlink\" id=\"body\">"

    outputFile.writ e(outdata);

    print >>outputFile, "</svg>"


    Comment

    • Gary Herron

      #3
      Re: Declare a variable global

      yinglcs@gmail.c om wrote:
      Hi,
      >
      I have the following code:
      >
      colorIndex = 0;
      >
      def test():
      print colorIndex;
      >
      This won't work. But it works if i do this:
      >
      Yes, it does work. Can you be more explicit about why you think it doesn't?

      (Also, this is Python not C/C++. Get *RID* of the semi-colons after your
      statements!)
      colorIndex = 0;
      >
      def test():
      global colorIndex;
      print colorIndex;
      >
      If you wish to change the value of colorIndex inside test, then this
      won't work

      colorIndex = 0

      def test():
      colorIndex=123 # creates a new variable within test

      In the above case you'll end up with two variables of that name, one in the global context, and the other within test's context.

      However, this code might be more what you want:

      colorIndex = 0

      def test():
      global colorIndex
      colorIndex=123 # changes the value of the global


      Better yet, restructure your code to not rely on the global statement. Do something like this if you can:


      def test():
      return 123

      colorIndex = test()

      Gary Herron
      My question is why do I have to explicit declaring 'global' for
      'colorIndex'? Can't python automatically looks in the global scope
      when i access 'colorIndex' in my function 'test()'?
      >
      Thank you.
      >
      >

      Comment

      • Peter Otten

        #4
        Re: Declare a variable global

        yinglcs@gmail.c om wrote:
        On Feb 19, 11:09 am, Jean-Paul Calderone <exar...@divmod .comwrote:
        >On 19 Feb 2007 09:04:19 -0800, "ying...@gmail. com" <ying...@gmail. com>
        >wrote:
        >>
        >Hi,
        >>
        >I have the following code:
        >>
        >colorIndex = 0;
        >>
        >def test():
        print colorIndex;
        >>
        >This won't work.
        >>
        >Are you sure?
        >>
        > exarkun@charm:~ $ cat foo.py
        > colorIndex = 0
        >>
        > def test():
        > print colorIndex
        >>
        > test()
        > exarkun@charm:~ $ python foo.py
        > 0
        > exarkun@charm:~ $
        >>
        >The global keyword lets you rebind a variable from the module scope. It
        >doesn't have much to do with accessing the current value of a variable.
        >>
        >Jean-Paul
        >
        Thanks. Then I don't understand why I get this error in line 98:
        >
        Traceback (most recent call last):
        File "./gensvg.py", line 109, in ?
        outdata, minX, minY, maxX, maxY = getText(data);
        File "./gensvg.py", line 98, in getText
        print colorIndex;
        UnboundLocalErr or: local variable 'colorIndex' referenced before
        assignment
        When there is an assignment python assumes that the variable is in the local
        scope (unless you explicitly declare it as global):
        >>v = 42
        >>def f():
        .... print v
        ....
        >>f()
        42
        >>def g():
        .... print v
        .... v = "won't get here anyway"
        ....
        >>g()
        Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "<stdin>", line 2, in g
        UnboundLocalErr or: local variable 'v' referenced before assignment
        >>def h():
        .... global v
        .... print v
        .... v = "for all the world to see"
        ....
        >>h()
        42
        >>v
        'for all the world to see'

        Peter

        Comment

        • Bjoern Schliessmann

          #5
          Re: Declare a variable global

          yinglcs@gmail.c om wrote:
          I have the following code:
          >
          colorIndex = 0;
          >
          def test():
          print colorIndex;
          Don't use ";". It's redundant.
          This won't work. But it works if i do this:
          >
          colorIndex = 0;
          >
          def test():
          global colorIndex;
          print colorIndex;
          >
          My question is why do I have to explicit declaring 'global' for
          'colorIndex'?
          Because you could want to have an identifier called colorIndex in
          test's scope. Globals are infrequently used in Python, thus the
          more common case is assumed by default.
          Can't python automatically looks in the global scope when i
          access 'colorIndex' in my function 'test()'?
          No, it can't looks.

          Regards,


          Björn

          --
          BOFH excuse #66:

          bit bucket overflow

          Comment

          • Terry Reedy

            #6
            Re: Declare a variable global

            | Here is my complete script:
            | #!/usr/bin/python
            |
            | import re
            | import sys
            | import time
            | import os
            | import shutil
            |
            | colors = ["#FF0000", "#00FF00", "#0000FF",
            | "#FFFF00" ,"#FFA500" ,"#DA70D6"]
            | colorIndex = 0
            |
            | def getText( intputstr):
            | rc = ""
            |
            | maxX = 0;
            | maxY = 0;
            | minX = 10000000;
            | minY = 10000000;
            |
            |
            | for str in intputstr:
            |
            | print str;
            |
            | if str != "":
            | pattern = "x:(\d+) y:(\d+) w:(\d+) h:(\d+) (.*)"
            |
            | match = re.findall(patt ern, str)
            |
            | if match:
            | x, y, width, height, area = match[0]
            |
            | colorIndex = colorIndex + 1
            |
            | rc = rc + "<rect x=\"%(x)s\" y=\"%(y)s\" width=\"%
            | (width)s\" height=\"%(heig ht)s\" " % locals()
            |
            | rc = rc + "fill=\"%s\ " stroke=\"#00000 0\" stroke-width=
            | \"1px\" fill-opacity=\".5\" />\n" % colors[colorIndex % len(colors)]
            |
            | _x = int(x)
            | _y = int(y)
            | _width = int(width)
            | _height = int(height)
            |
            | minX = min(minX, _x);
            | minY = min(minY, _y);
            |
            | maxX = max(maxX, _x+ _width);
            | maxY = max(maxY, _y+_height);
            |
            |
            |
            | else:
            | pattern = "\((\d+),(\d+)\ )\((\d+),(\d+)\ )(.*)"
            |
            | match = re.findall(patt ern, str)
            |
            | if match:
            | x1, y1, x2, y2, ignore = match[0]
            |
            | rc = rc + "<line x1=\"%(x1)s\" y1=\"%(y1)s\" x2=\"%
            | (x2)s\" y2=\"%(y2)s\" style=\"stroke: rgb(99,99,99);s troke-width:2\" /
            | >" % locals()
            | rc = rc + "\n"
            |
            | _x1 = int(x1)
            | _y1 = int(y1)
            | _x2 = int(x2)
            | _y2 = int(y2)
            |
            | minX = min(_x1, _x2);
            | minY = min(_y1, _y2);
            |
            | maxX = max(_x1, _x2);
            | maxY = max(_y1, _y2);
            |
            | print colorIndex;
            |
            | print "match 2!"
            |
            |
            | return rc, minX, minY, maxX, maxY;
            |
            | fileName = sys.argv[1]
            |
            | inputFile = open(fileName, 'r')
            | data = inputFile.readl ines();
            | outdata, minX, minY, maxX, maxY = getText(data);
            |
            | print minX, minY, maxX, maxY
            |
            | outputFile = open(fileName + '.svg', 'w')
            |
            | print >outputFile, "<svg xmlns=\"http://www.w3.org/2000/svg\"
            | xmlns:xlink=\"h ttp://www.w3.org/1999/xlink\" id=\"body\">"
            |
            | outputFile.writ e(outdata);
            |
            | print >>outputFile, "</svg>"
            |
            |
            | --
            | http://mail.python.org/mailman/listinfo/python-list
            |



            Comment

            • Bruno Desthuilliers

              #7
              Re: Declare a variable global

              yinglcs@gmail.c om a écrit :
              Hi,
              >
              I have the following code:
              >
              colorIndex = 0;
              You don't need the ;
              >
              def test():
              print colorIndex;
              Idem.
              This won't work.
              Why ?

              Or more exactly : for which definition of "won't work" ? (hint: this
              code prints 0 on sys.stdout - I don't know what else you where expecting...)
              But it works if i do this:
              >
              colorIndex = 0;
              >
              def test():
              global colorIndex;
              print colorIndex;
              Have mercy : keep those ; out of here.
              My question is why do I have to explicit declaring 'global' for
              'colorIndex'? Can't python automatically looks in the global scope
              when i access 'colorIndex' in my function 'test()'?
              It does. You only need to declare a name global in a function if you
              intend to rebind the name in the function.

              Comment

              • Bruno Desthuilliers

                #8
                Re: Declare a variable global

                yinglcs@gmail.c om a écrit :
                On Feb 19, 11:09 am, Jean-Paul Calderone <exar...@divmod .comwrote:
                >
                >>On 19 Feb 2007 09:04:19 -0800, "ying...@gmail. com" <ying...@gmail. comwrote:
                >>
                >>
                >>>Hi,
                >>
                >>>I have the following code:
                >>
                >>>colorIndex = 0;
                >>
                >>>def test():
                >> print colorIndex;
                >>
                >>>This won't work.
                >>
                >>Are you sure?
                >>
                > exarkun@charm:~ $ cat foo.py
                > colorIndex = 0
                >>
                > def test():
                > print colorIndex
                >>
                > test()
                > exarkun@charm:~ $ python foo.py
                > 0
                > exarkun@charm:~ $
                >>
                >>The global keyword lets you rebind a variable from the module scope. It
                >>doesn't have much to do with accessing the current value of a variable.
                >>
                >>Jean-Paul
                >
                >
                Thanks. Then I don't understand why I get this error in line 98:
                >
                Traceback (most recent call last):
                File "./gensvg.py", line 109, in ?
                outdata, minX, minY, maxX, maxY = getText(data);
                File "./gensvg.py", line 98, in getText
                print colorIndex;
                UnboundLocalErr or: local variable 'colorIndex' referenced before
                assignment
                >
                >
                Here is my complete script:
                #!/usr/bin/python
                >
                import re
                import sys
                import time
                import os
                import shutil
                >
                colors = ["#FF0000", "#00FF00", "#0000FF",
                "#FFFF00" ,"#FFA500" ,"#DA70D6"]
                colorIndex = 0
                >
                def getText( intputstr):
                rc = ""
                >
                maxX = 0;
                maxY = 0;
                minX = 10000000;
                minY = 10000000;
                >
                >
                for str in intputstr:
                don't use str as an indentifier unless it's ok for you to shadow the
                builtin type str.
                print str;
                >
                if str != "":
                if str:
                pattern = "x:(\d+) y:(\d+) w:(\d+) h:(\d+) (.*)"
                match = re.findall(patt ern, str)
                Move loop invariants (here, your pattern) outside of the loop. And while
                you're at it, compile it.
                if match:
                x, y, width, height, area = match[0]
                >
                colorIndex = colorIndex + 1
                You're not reading colorIndex, you're rebinding it. In this case, you do
                need to declare it global (or better, to rethink your code to avoid
                globals).
                rc = rc + "<rect x=\"%(x)s\" y=\"%(y)s\" width=\"%
                (width)s\" height=\"%(heig ht)s\" " % locals()
                Using augmented assignment (ie : +=) may be more readable here (MHO).
                Also, if you use single quotes for the template string, you can save the
                escapes:
                rc += '<rect x="%(x)s" y="%(y)s" width="%
                (width)s " height="%(heigh t)s' " % locals()

                And FWIW, you might want to define the template string outside the loop.
                rc = rc + "fill=\"%s\ " stroke=\"#00000 0\" stroke-width=
                \"1px\" fill-opacity=\".5\" />\n" % colors[colorIndex % len(colors)]
                idem

                (snip)


                Comment

                • Steve Holden

                  #9
                  Re: Declare a variable global

                  yinglcs@gmail.c om wrote:
                  On Feb 19, 11:09 am, Jean-Paul Calderone <exar...@divmod .comwrote:
                  >On 19 Feb 2007 09:04:19 -0800, "ying...@gmail. com" <ying...@gmail. comwrote:
                  >>
                  >>Hi,
                  >>I have the following code:
                  >>colorIndex = 0;
                  >>def test():
                  >> print colorIndex;
                  >>This won't work.
                  >Are you sure?
                  >>
                  > exarkun@charm:~ $ cat foo.py
                  > colorIndex = 0
                  >>
                  > def test():
                  > print colorIndex
                  >>
                  > test()
                  > exarkun@charm:~ $ python foo.py
                  > 0
                  > exarkun@charm:~ $
                  >>
                  >The global keyword lets you rebind a variable from the module scope. It
                  >doesn't have much to do with accessing the current value of a variable.
                  >>
                  >Jean-Paul
                  >
                  Thanks. Then I don't understand why I get this error in line 98:
                  >
                  Traceback (most recent call last):
                  File "./gensvg.py", line 109, in ?
                  outdata, minX, minY, maxX, maxY = getText(data);
                  File "./gensvg.py", line 98, in getText
                  print colorIndex;
                  UnboundLocalErr or: local variable 'colorIndex' referenced before
                  assignment
                  >
                  >
                  Here is my complete script:
                  [... script elided ...]

                  Well, now I've seen the error message I don't even need to see the
                  script to explain what's going on. Unfortunately in your (entirely
                  creditable) attempt to produce the shortest possible script that showed
                  the error you presented a script that *didn't* have the error.

                  Python determines whether names inside a function body are local to the
                  function or global to the module by analyzing the function source. If
                  there are bindings (assignments) to the name inside the body then the
                  name is assumed to be local to the function unless a global statement
                  declares otherwise.

                  regards
                  Steve
                  --
                  Steve Holden +44 150 684 7255 +1 800 494 3119
                  Holden Web LLC/Ltd http://www.holdenweb.com
                  Skype: holdenweb http://del.icio.us/steve.holden
                  Blog of Note: http://holdenweb.blogspot.com
                  See you at PyCon? http://us.pycon.org/TX2007

                  Comment

                  Working...