UnboundLocalError - Python错误

时间:2016-06-26 18:24:51

标签: python csv variables local

我的代码出现以下错误:

UnboundLocalError: local variable 'row' referenced before assignment

我尝试了很多东西,但没有任何效果。我怀疑围绕'quantityQuestion'子程序做了些什么。根据脚本编写者的说法,问题出在第97行。

import csv
import sys

global totalPrice
totalPrice = 0

addItem = ""
gtinNum = ""
quantity = 0
restart = ""

global receipt
receipt = open("receipt.txt", "w+")
global restockTxt
restockTxt = open("restock.txt", "w+")
global price
price = 0
global file2
file2 = open("ChocolateCSV2.csv", "r")
global file2w
file2w = open("ChocolateCSV2.csv", "w", newline="")

def restart():
    restart = input("Would you like to restart? Y/N")

    if restart.lower() == "y":
        actionQ()
    else:
        print("Exiting program.")
        file2.close()
        sys.exit()

def priceSub(): #Defining the restart subprogram
    priceQ = input("Would you like to add an item? Y/N") #Asks the user if they would like to add an item.
    global totalPrice #Declaring totalPrice and making it global.
    totalPrice = int(price) + totalPrice #Setting totalPrice to add the variable price to itself.

    if priceQ.lower() == "y": #If statement that checks to see if the user has entered a "y".
        gtinQuestion() #If it is true, it will start the gtinQuestion subprogram.
    else: #Anything other than a "y" will do the following commands.
        global receiptCont #Declaring the receipt content as a global variable.
        receiptCont = receipt.read() #Reads the receipt.
        receipt.close() #Closes the file.
        print(receiptCont) #Prints the content of the receipt.
        print("Total Price: " + "%.2f" % round(totalPrice, 2)) #Prints the totalPrice variable rounded to two decimal places.
        restart()

def quantityQuestion(): #Defining the subprogram for the quantity.
    quantity = input("How much would you like?") #Asks the user how much of the item they would like.
    if quantity.isdigit() == False: #If statement to check whether or not the user has entered an integer or not.
        quantityQuestion() #If they have not entered an integer, it will ask the question again.
    global price #Declaring the variable price as a global variable.
    price = "" #Setting price to an empty string.

    reader = csv.reader(file2, delimiter = ",")
    csvList = list(reader)

    for row in csvList: #Loop that seperates each row in the CSV
        if str(gtinNum) in row: #If statement to check if the GTIN given by the user is in the CSV.
            receipt.write(str(row) + "\n") #If it is in one of the CSV rows, it will write the row to the text file.
            receipt.write(str("- Quantity: " + quantity + "\n")) #It also writes the quantity given by the user.
            price = float(row[2]) * int(quantity) #The price is the price given by the CSV file multiplied by the quantity.
            receipt.write("- Price: " + str("%.2f" % round(price, 2)) + "\n") #The final price (after the multiplication) is written to the text file also.
            row[2] = row[2] - quantity
            writeCSV = csv.writer(file2w)
            writeCSV.writerow(row)
            file2w.close()
            priceSub() #Starts the restart subprogram.
            break #Breaks the loop.
    else:
            print("The code entered could not be found - Please re-enter") #If it is not in the CSV it will print this error message.
            gtinQuestion() #Starts the gtinQuestion subprogram.

def gtinQuestion(): #Defining the gtinQuestion subprogram.
    global gtinNum #Declaring the gtinNum variable as global.
    gtinNum = input("Please enter the GTIN-8 Code of the product you would like to order:") #Setting that variable to the initial question.

    if gtinNum.isdigit() == False or len(gtinNum) != 8: #If the code given is not an integer or is not 8 digits long...
        print("Please re-enter your GTIN-8 code - Reason: Invalid Code") #It will print this error message and ask the question again.
        gtinQuestion()
    elif gtinNum.isdigit() == True and len(gtinNum) == 8: #If it is an integer and is 8 digits long...
        quantityQuestion() #It will start the quantityQuestion subprogram.

def restockAction():
    reader = csv.reader(file2, delimiter = ",")
    csvList = list(reader)
    for row in csvList:
        stDiff = float(row[5]) - float(row[3])
        if float(row[3]) <= float(row[4]):
            restockTxt.write(row[0]+" | "+row[1]+" | "+"Stock Replenished: "+(str(stDiff)+"\n"))
            restockTxt.close()
            row[3] = row[5]
            writeCSV = csv.writer(file2w)
            writeCSV.writerows(csvList)
            file2w.close()
    else:
            if float(row[3]) >= float(row[4]):
            restockTxt.write("No (other) stock needs to be replenished.")
            restockTxt.close()
            restockRead = open("restock.txt", "r")
            print(restockRead.read())
            restart()


def actionQ():
    restock = input("What action would you like to perform?:\n Restock (Enter 1)\n Order (Enter 2)")

    if restock == "1" or restock == "restock":
        print("Restock Action Requested...")
        restockAction()
    elif restock == "2" or restock == "order":
        print("Ordering action Requested...")
        gtinQuestion()
    else:
        actionQ()

actionQ()

感谢任何帮助,

感谢。

2 个答案:

答案 0 :(得分:1)

问题出在restockAction()

for row in csvList:
    # some code
else:
    if float(row[3]) >= float(row[4]):
#             ^ 

如果csvList中没有行,row将没有任何值,因为for将不会被执行,但else块将被执行。

因此row的{​​{1}}块中的else尚未定义。

您是否打算将for附加到else,而不是if

for

答案 1 :(得分:0)

在检查row [index]是否有值之前,您必须验证是否有任何行:

else:
    if row and float(row[3]) >= float(row[4]):
        restockTxt.write("No (other) stock needs to be replenished.")
        restockTxt.close()
        restockRead = open("restock.txt", "r")
        print(restockRead.read())
        restart()

if row and ...充当先锋,保护解释器不执行row [index]。如果row是Noneif row == False并且它立即返回而不评估语句的其余部分。