Python在赋值之前引用了局部变量

时间:2014-03-11 18:26:50

标签: python python-3.x local-variables

我正在学校为我的计算GCSE开发货币转换器,我不知道我在这里做错了什么。

我的代码是:

PD = 1.66401 # declare pounds to dollars exchange rate

def Convert(ex): #converting sub... ex = exchange rate
    amount = input("Enter amount to convert: ") #get amount to convert
    result = round(float(amount) * float(ex),2) #calculate result using PD rate
    print("result = " + str(result)) #print result

def Change(ex): #change sub... ex = echange rate
    newex = input("Enter new exchange rate: ") #allow user to enter new exchange rate
    if ex == PD: #check what exchange rate to change (needed because final version will have alot more options
        PD = float(newex) #change exchange rate

#display menu
menu = input("1.Convert\n2.Modify exchange rate\nPlease select option: ")
if menu == "1":
    Convert(PD) #Call sub...convert using pounds to dollars
elif menu == "2":
    Change(PD) #Call sub...change pounds to dollars exchange rate

当我转换它正常工作但在更改汇率时我收到以下错误:

Traceback (most recent call last):
  File "F:/USB/Computing/Programming/Python/test2.py", line 18, in <module>
    Change(PD) #Call sub...change pounds to dollars echange rate
  File "F:/USB/Computing/Programming/Python/test2.py", line 10, in Change
    if ex == PD: #check what exchange rate to change (needed because final version will have alot more options
UnboundLocalError: local variable 'PD' referenced before assignment

我已经四处寻找但没有回答非常有帮助 如果你能尽可能简单地尝试并保持任何解释,并提供一个例子,说明我出错的地方以及我应该做的事情,我将不胜感激。

3 个答案:

答案 0 :(得分:3)

def Change(ex): #change sub... ex = echange rate
    global PD
    newex = input("Enter new exchange rate: ") #allow user to enter new exchange rate
    if ex == PD: #check what exchange rate to change (needed because final version will have alot more options
        PD = float(newex) #change exchange rate

Python docs中的更多信息:

  

在代码块中使用名称时,使用最近的名称解析   封闭范围。代码块可见的所有此类范围的集合是   称为区块的环境。

     

如果名称绑定在块中,则它是该块的局部变量,   除非声明为非本地。如果名称在模块级别绑定,   它是一个全局变量。 (模块代码块的变量是   本地和全局。)如果在代码块中使用变量但不是   在那里定义,它是一个自由变量。

     

如果根本找不到名称,则会引发NameError异常。 如果   名称是指尚未绑定的局部变量,a   引发UnboundLocalError异常。 UnboundLocalError是一个子类   NameError。

答案 1 :(得分:1)

这是一个非常有用的课程的好例子。通过将PD声明为类属性,您可以使用@property装饰器来保持代码的有序性,而不必担心全局变量。

class CurrencyConverter(object):

    def __init__(self):
        """
        Set the default exchange rate to Pounds to U.S. Dollars
        """
        self.PD = 1.66401

    @property
    def PD(self):
        return self._PD

    @PD.setter
    def PD(self, value):
        """
        Set and ensure PD is a float value.
        """
        self._PD = float(value)

    def convert(self):
        """
        Takes user input and returns exchanged value.
        """
        amount = input("Enter amount to convert: ")
        result = round(float(amount) * self.PD, 2)
        print "result = %.2f\n" % result

    def change(self):
        """
        Takes user input and changes exchange rate.
        """
        newex = input("New exchange rate: ")
        self.PD = newex

这种方法的好处是,如果你的下一个任务是扩展你的货币转换器,那么很容易添加方法或继承这个类:

class CanadianExchangeRate(CurrencyConverter):
    """
    Converts Canadian Dollars to U.S. Dollars.
    """
    def __init__(self):
        self.PD = 0.90

答案 2 :(得分:0)

您可以从内部函数访问全局变量。但是,如果要修改其值,则需要先使用global并将它们声明为全局范围:

def Change(ex):
    ##########
    global PD
    ##########
    newex = input("Enter new exchange rate: ")
    if ex == PD:
        PD = float(newex)