Local variable referenced before assignment?

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)#, column2, urls)
   #feed = 0
   if not result:
        print "Request failed"
    fo.write(column1)
    fo.write(',')
    fo.write(column2)
    fo.write(',')
    #fo.write(urls)
    fo.write(',')
    fo.write('404,image not createdn')
    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)#,column2,urls,'200','image created','/n')
    fo.write(',')
    fo.write(column2)
    fo.write(',')
    #fo.write(urls)
    fo.write(',')
    fo.write('200,image createdn')
    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)#,column2,urls,'200','image created','/n')

Any idea why?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

Put a global statement at the top of your function and you should be good:

def onLoadFinished(result):
    global feed
    ...

To demonstrate what I mean, look at this little test:

x = 0
def t():
    x += 1
t()

this blows up with your exact same error where as:

x = 0
def t():
    global x
    x += 1
t()

does not.

The reason for this is that, inside t, Python thinks that x is a local variable. Furthermore, unless you explicitly tell it that x is global, it will try to use a local variable named x in x += 1. But, since there is no x defined in the local scope of t, it throws an error.

Method 3

As the Python interpreter reads the definition of a function (or, I think, even a block of indented code), all variables that are assigned to inside the function are added to the locals for that function. If a local does not have a definition before an assignment, the Python interpreter does not know what to do, so it throws this error.

The solution here is to add

global feed

to your function (usually near the top) to indicate to the interpreter that the feed variable is not local to this function.

Method 4

in my case that exact same error was triggered by a typo !
I thought my my var name was

varAlpha

but in the code i had defined

varalpha

& got the error

UnboundLocalError: local variable 'varAlpha' referenced before assignment

when calling varAlpha

I hope it helps somebody one day searching for that error & wondering (as my search for that error led me here while being unrelated with the use of global or not global which was a head scratcher !)

Method 5

You can do like this for the function scope

def main()

  self.x = 0

  def incr():
    self.x += 1
  
  for i in range(5):
     incr()
  
  print(self.x)


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x