Python在赋值前引用了局部变量
我正在为学校的计算机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 个回答
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
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 文档:
当在代码块中使用一个名字时,Python 会从最近的外部范围中查找这个名字。所有这些代码块可见的范围被称为这个块的环境。
如果在一个代码块中给一个名字赋值,那么这个名字就是这个块的局部变量,除非你特别声明它为非局部变量。如果在模块级别给名字赋值,那么它就是全局变量。(模块代码块中的变量可以是局部的也可以是全局的。)如果在代码块中使用了一个变量,但没有在这里定义它,那么这个变量就是自由变量。
当找不到一个名字时,会抛出一个 NameError 异常。如果这个名字指向一个还没有被赋值的局部变量,会抛出一个 UnboundLocalError 异常。UnboundLocalError 是 NameError 的一个子类。
0
你可以在函数里面正常使用全局变量。但是,如果你想要修改这些变量的值,就需要先用 global
这个关键词,告诉程序这些变量是全局的:
def Change(ex):
##########
global PD
##########
newex = input("Enter new exchange rate: ")
if ex == PD:
PD = float(newex)