Jason White
Jason White

Reputation: 686

Unbound local variable Python 3.2

This error pops up randomly, and I'm pretty sure it's because the infoGotten variable isn't initialized before the return statement calls it. The part that has me puzzled is how it's getting to that part of the code to produce that error in the first place. Hopefully someone can explain to me why that is as I haven't been able to figure it out yet. I'm guessing it's because of the try/except statement but I did some searching and checked 7.4 in the manual and it doesn't appear (to me anyways) that I'm doing something incorrect.

breakLoop = 0
def get_item_info(linkParameters):
    global breakLoop
    nheaders = {'User-Agent' : 'Firefox/15.0.1'}
    purl = 'http://example.com/something.php'
    pd = linkParameters
    nreq = urllib.request.Request(purl, pd, nheaders)
    if breakLoop >= 4:
        return 'Request timed out {} times'.format(breakLoop)
    try:
        nresponse = urllib.request.urlopen(nreq)
    except urllib.error.URLError:
        breakLoop += 1
        get_item_info(pd)
    except urllib.error.HTTPError:
        breakLoop += 1
        get_item_info(pd)        
    else:
        infoGotten = nresponse.read()
    return infoGotten

Thanks!

Upvotes: 0

Views: 278

Answers (1)

Andrew Clark
Andrew Clark

Reputation: 208525

You need to return the results of the recursive calls, so it should be return get_item_info(pd) in the except clauses (which I combined below):

breakLoop = 0
def get_item_info(linkParameters):
    nheaders = {'User-Agent' : 'Firefox/15.0.1'}
    purl = 'http://example.com/something.php'
    pd = linkParameters
    nreq = urllib.request.Request(purl, pd, nheaders)
    if breakLoop >= 4:
        return 'Request timed out {} times'.format(breakLoop)
    try:
        nresponse = urllib.request.urlopen(nreq)
    except (urllib.error.URLError, urllib.error.HTTPError):
        breakLoop += 1
        return get_item_info(pd)
    else:   
        return nresponse.read()

Recursion seems like a weird way to perform the retries though, why not use a loop? The following seems more clear:

def get_item_info(linkParameters):
    nheaders = {'User-Agent' : 'Firefox/15.0.1'}
    purl = 'http://example.com/something.php'
    pd = linkParameters
    for i in range(5):
        nreq = urllib.request.Request(purl, pd, nheaders)
        try:
            nresponse = urllib.request.urlopen(nreq)
            return nresponse.read()
        except (urllib.error.URLError, urllib.error.HTTPError):
            pass
    return 'Request timed out 4 times'

Upvotes: 3

Related Questions