局部变量 'servers' 在赋值前引用

5 投票
3 回答
5706 浏览
提问于 2025-04-17 19:04
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

但是我在编译代码时遇到了这个错误:

异常类型:UnboundLocalError

异常值:在赋值之前引用了局部变量 'servers'

异常位置:/home/amine/PFE Directory/mysite1/myform/Webservice.py 的 websvc 函数,行 43

Python 执行文件:/usr/bin/python2.7

在我给这个函数添加参数之前,这段代码是正常工作的。

3 个回答

0

你可以在尝试块(try block)里面创建一个空变量,只要在尝试块之后检查一下 globals() 里的变量就行。虽然这样做对这段代码没有太大影响,因为创建一个新的空列表是不会出错的,但我可以把连接的打开放在 try 块里,这样如果出错了就能捕捉到,然后我可以在 finally 块里关闭这个对象,而不需要在 try/except/finally 块之前先创建一个空对象(已经测试过了)。

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 []

这个部分没有测试过。如果在 servers.append(result) 这行出错,可以在这之前试试 if 'servers' in globals():。这样做可能会导致 try 块的代码出错,所以我希望不需要这样做。在我的例子中,当我在 try 块里使用连接时,也没有遇到这个问题。

顺便提一下:append() 会创建一个完整的副本。如果你要增加一个很大的列表,可以试试 servers.extend([result]),不过如果你只是增加几个服务器,这种情况不太可能。

0

我现在明白问题了,你已经编辑过内容,补充了缺失的部分。问题出在异常处理上。

如果在 try 之后和 servers=[] 之前出现错误,程序会跳到 except 语句,然后看到 return servers,这时就会出错。

你可能想用 list(),而不是用 dict() 来模拟一个列表……

6

你的代码没有到达服务器初始化的步骤,所以才会出现错误。只需要把初始化的部分放在try..except之前就可以了。这样改:

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

撰写回答