Local variable referenced before assignment?
python, python-2.7, python-3.x, variable-assignment
Solution
When Python parses the body of a function definition and encounters an assignment such as
feed = ...
Python interprets `feed` as a local variable by default. If you do not wish for it to be a local variable, you must put
global feed
in the function definition. The global statement does not have to be at the beginning of the function definition, but that is where it is usually placed. Wherever it is placed, the global declaration makes `feed` a global variable everywhere in the function.
Without the global statement, since `feed` is taken to be a local variable, when Python executes
feed = feed + 1,
Python evaluates the right-hand side first and tries to look up the value of feed. The first time through it finds `feed` is undefined. Hence the error.
The shortest way to patch up the code is to add `global feed` to the beginning of `onLoadFinished`. The nicer way is to use a class:
class Page(object):
def __init__(self):
self.feed = 0
def onLoadFinished(self, result):
...
self.feed += 1
The problem with having functions which mutate global variables is that it makes it harder to grok your code. Functions are no longer isolated units. Their interaction extends to everything that affects or is affected by the global variable. Thus it makes larger programs harder to understand.
By avoiding mutating globals, in the long run your code will be easier to understand, test and maintain.
Problem
I am using the PyQt library to take a screenshot of a webpage, then reading through a CSV file of different URLs. I am keeping a variable feed that incremements everytime a URL is processed and therefore should increment to the number of URLs. Here's code: ``` webpage = QWebPage() fo = open("C:/Users/Romi/Desktop/result1.txt", "w") feed = 0 def onLoadFinished(result): #fo.write( column1[feed])#, column2[feed], urls[feed]) #feed = 0 if not result: print "Request failed" fo.write(column1[feed]) fo.write(',') fo.write(column2[feed]) fo.write(',') #fo.write(urls[feed]) fo.write(',') fo.write('404,image not created\n') feed = feed + 1 sys.exit(1) save_page(webpage, outputs.pop(0)) # pop output name from list and save if urls: url = urls.pop(0) # pop next url to fetch from list webpage.mainFrame().load(QUrl(url)) fo.write(column1[feed])#,column2[feed],urls[feed],'200','image created','/n') fo.write(',') fo.write(column2[feed]) fo.write(',') #fo.write(urls[feed]) fo.write(',') fo.write('200,image created\n') feed = feed + 1 else: app.quit() # exit after last url webpage.connect(webpage, SIGNAL("loadFinished(bool)"), onLoadFinished) webpage.mainFrame().load(QUrl(urls.pop(0))) #fo.close() sys.exit(app.exec_()) ``` It gives me the error: ``` local variable feed referenced before the assignment at fo.write(column1[feed])#,column2[feed],urls[feed],'200','image created','/n') ``` Any idea why?