Declare a variable global

Y

yinglcs

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.
 
Y

yinglcs

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>"
 
G

Gary Herron

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
 
P

Peter Otten

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):
.... print v
........ print v
.... v = "won't get here anyway"
....Traceback (most recent call last):
File "<stdin>", line 1, in <module>
.... global v
.... print v
.... v = "for all the world to see"
....'for all the world to see'

Peter
 
B

Bjoern Schliessmann

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
 
T

Terry Reedy

| 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
|
 
B

Bruno Desthuilliers

(e-mail address removed) 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.
 
S

Steve Holden

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
 
B

Bruno Desthuilliers

(e-mail address removed) a écrit :
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)
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top