madtyn madtyn - 5 months ago 9
Python Question

Python: Why two global variables have different behaviours?

I have a piece of code like this further down.

With this code I get a:

local variable 'commentsMade' referenced before assignment


Why do I need a 'global commentsMade' statement in the first function but I don't need with TARGET_LINES? (using Python2.7)

TARGET_LINE1 = r'someString'
TARGET_LINE2 = r'someString2'
TARGET_LINES = [TARGET_LINE1, TARGET_LINE2]
commentsMade = 2

def replaceLine(pattern, replacement, line, adding):

#global commentsMade # =========> Doesn't work. Uncommenting this does!!!!

match = re.search(pattern, line)
if match:
line = re.sub(pattern, replacement, line)
print 'Value before = %d ' % commentsMade
commentsMade += adding
print 'Value after = %d ' % commentsMade
return line

def commentLine(pattern, line):
lineToComment = r'(\s*)(' + pattern + r')(\s*)$'
return replaceLine(lineToComment, r'\1<!--\2-->\3', line, +1)

def commentPomFile():
with open('pom.xml', 'r+') as pomFile:
lines = pomFile.readlines()
pomFile.seek(0)
pomFile.truncate()

for line in lines:
if commentsMade < 2:

for targetLine in TARGET_LINES: # ===> Why this works???

line = commentLine(targetLine, line)

pomFile.write(line)

if __name__ == "__main__":
commentPomFile()

Answer

If you make an assignment to a variable in the body of a function, then Python treats the variable as local (unless you declare it global). If you just read the value within the body of a function, without assigning to it, then it looks for the variable in a higher scope (e.g., parent function or global).

So in your case, the difference is that you assign to commentsMade, which makes it local, but you don't assign to TARGET_LINES, so it looks for a global definition for it.

Comments