Declare a variable global

Discussion in 'Python' started by yinglcs@gmail.com, Feb 19, 2007.

  1. Guest

    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.
    , Feb 19, 2007
    #1
    1. Advertising

  2. Guest

    On Feb 19, 11:09 am, Jean-Paul Calderone <> wrote:
    > On 19 Feb 2007 09:04:19 -0800, "" <> 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;
    UnboundLocalError: 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(pattern, 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=\"%(height)s\" " % locals()

    rc = rc + "fill=\"%s\" stroke=\"#000000\" 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(pattern, 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);stroke-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.readlines();
    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=\"http://www.w3.org/1999/xlink\" id=\"body\">"

    outputFile.write(outdata);

    print >>outputFile, "</svg>"
    , Feb 19, 2007
    #2
    1. Advertising

  3. Gary Herron Guest

    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.
    >
    >
    Gary Herron, Feb 19, 2007
    #3
  4. Peter Otten Guest

    wrote:

    > On Feb 19, 11:09 am, Jean-Paul Calderone <> wrote:
    >> On 19 Feb 2007 09:04:19 -0800, "" <>
    >> 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;
    > UnboundLocalError: 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
    UnboundLocalError: 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
    Peter Otten, Feb 19, 2007
    #4
  5. 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
    Bjoern Schliessmann, Feb 19, 2007
    #5
  6. Terry Reedy Guest

    | 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(pattern, 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=\"%(height)s\" " % locals()
    |
    | rc = rc + "fill=\"%s\" stroke=\"#000000\" 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(pattern, 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);stroke-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.readlines();
    | 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=\"http://www.w3.org/1999/xlink\" id=\"body\">"
    |
    | outputFile.write(outdata);
    |
    | print >>outputFile, "</svg>"
    |
    |
    | --
    | http://mail.python.org/mailman/listinfo/python-list
    |
    Terry Reedy, Feb 19, 2007
    #6
  7. 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.
    Bruno Desthuilliers, Feb 19, 2007
    #7
  8. Steve Holden Guest

    wrote:
    > On Feb 19, 11:09 am, Jean-Paul Calderone <> wrote:
    >> On 19 Feb 2007 09:04:19 -0800, "" <> 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;
    > UnboundLocalError: 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
    Steve Holden, Feb 19, 2007
    #8
  9. a écrit :
    > On Feb 19, 11:09 am, Jean-Paul Calderone <> wrote:
    >
    >>On 19 Feb 2007 09:04:19 -0800, "" <> 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;
    > UnboundLocalError: 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(pattern, 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=\"%(height)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="%(height)s' " % locals()

    And FWIW, you might want to define the template string outside the loop.

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


    idem

    (snip)
    Bruno Desthuilliers, Feb 19, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. khawar
    Replies:
    1
    Views:
    7,286
    GastonQ
    Jul 10, 2003
  2. Miguel Dias Moura

    How to declare a variable in the global scope?

    Miguel Dias Moura, Dec 14, 2004, in forum: ASP .Net
    Replies:
    41
    Views:
    10,820
    Vikesh Arora
    Dec 27, 2004
  3. Replies:
    18
    Views:
    624
    Fredrik Lundh
    Nov 30, 2005
  4. Brian Sammon

    declare vs define of global variables

    Brian Sammon, Oct 5, 2004, in forum: C Programming
    Replies:
    7
    Views:
    492
    Flash Gordon
    Oct 8, 2004
  5. Louis
    Replies:
    2
    Views:
    3,906
    Louis
    Apr 30, 2007
Loading...

Share This Page