local variable 'servers' referenced before assignment

Question:

def websvc(currency):
    db = MySQLdb.connect("localhost", "root", "aqw", "PFE_Project")
    cursor = db.cursor()
    sql = "SELECT * FROM myform_composantsserveur"
        
    try:
        cursor.execute(sql)
        results = cursor.fetchall()
        currency_in = currency
        req = urllib2.urlopen('http://rate-exchange.appspot.com/currency?from=USD&to=%s') % (currency_in) 
        req1 = req.read()
        rate = int(req1['rate'])
        # rate = 0.77112893299999996
        
        servers = []
        for row in results:
            result = {} 
            result['1'] = row[1]
            result['3'] = int(row[2])
            result['4'] = int(row[3])
            result['5'] = int(row[4])
            result['6'] = row[5]
            result['7'] = int(row[6])
            result['8'] = row[7]
            result['9'] = row[8]
            p = rate * calculations_metric (int(row[2]), int(row[3]), int(row[4]), int(row[6]), row[7])
            result['2'] = p
            keys = result.keys()
            keys.sort()
            servers.append(result)
             
    except:
        print "Error: unable to fetch data"
    db.close()
    return servers

but i have this error while compiling the code :

Exception Type: UnboundLocalError

Exception Value: local variable
‘servers’ referenced before assignment

Exception Location: /home/amine/PFE Directory/mysite1/myform/Webservice.py in websvc, line 43 Python Executable: /usr/bin/python2.7

this code works normally before i added a parameter in this function

Asked By: Imoum

||

Answers:

Your code not able to reach servers initialization and that is why you getting error. Simply move initialization before try..except. Change this way:

def websvc(currency):
    db = MySQLdb.connect("localhost", "root", "aqw", "PFE_Project")
    cursor = db.cursor()
    sql = "SELECT * FROM myform_composantsserveur"
    servers = []

    try:
        cursor.execute(sql)
        results = cursor.fetchall()
        currency_in = currency
        req = urllib2.urlopen('http://rate-exchange.appspot.com/currency?from=USD&to=%s') % (currency_in) 
        req1 = req.read()
        rate = int(req1['rate'])
        # rate = 0.77112893299999996

        for row in results:
            result = {} 
            result['1'] = row[1]
            result['3'] = int(row[2])
            result['4'] = int(row[3])
            result['5'] = int(row[4])
            result['6'] = row[5]
            result['7'] = int(row[6])
            result['8'] = row[7]
            result['9'] = row[8]
            p = rate * calculations_metric (int(row[2]), int(row[3]), int(row[4]), int(row[6]), row[7])
            result['2'] = p
            keys = result.keys()
            keys.sort()
            servers.append(result)

    except:
        print "Error: unable to fetch data"
    db.close()
    return servers
Answered By: Artsiom Rudzenka

I see the problem now you have edited it to add the missing parts. It’s the exception handler.

If you have an error after try and before servers=[] it will jump to the except clause, then see return servers and fail.

You might want to use a list(), instead of using a dict() to emulate a list …

Answered By: user774340

You can make the empty variable also in the try block if you check against the globals() variables any time after the try block. This is no game changer in this code since making a new empty list will never fail, but I could use it to have the opening of a connection into the try block so that it would be caught in the exception, and I could close that object in the finally block without having to make an empty object before the try/except/finally block (tested).

def websvc(currency):
    db = MySQLdb.connect("localhost", "root", "aqw", "PFE_Project")
    cursor = db.cursor()
    sql = "SELECT * FROM myform_composantsserveur"

    try:
        servers = []
        cursor.execute(sql)
        results = cursor.fetchall()
        currency_in = currency
        req = urllib2.urlopen('http://rate-exchange.appspot.com/currency?from=USD&to=%s') % (currency_in) 
        req1 = req.read()
        rate = int(req1['rate'])
        # rate = 0.77112893299999996

        for row in results:
            result = {} 
            result['1'] = row[1]
            result['3'] = int(row[2])
            result['4'] = int(row[3])
            result['5'] = int(row[4])
            result['6'] = row[5]
            result['7'] = int(row[6])
            result['8'] = row[7]
            result['9'] = row[8]
            p = rate * calculations_metric (int(row[2]), int(row[3]), int(row[4]), int(row[6]), row[7])
            result['2'] = p
            keys = result.keys()
            keys.sort()
            servers.append(result)

    except:
        print "Error: unable to fetch data"
    db.close()

    if 'servers' in globals():
        return servers 
    else: 
        return []

This is untested. If it crashes at servers.append(result), try if 'servers' in globals(): right before that as well. Which would blow up the code of the try block, therefore, I hope that it is not needed, and in my example, I also did not have to do that when I used the called connection afterwards in the try block.

Side remark: append() makes a full copy. Try servers.extend([result]) instead if you grow a large list (not likely if you just count up just a few servers).

Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.