我已经阅读了关于这个主题的几乎所有其他问题,但我的代码仍然无法工作。
我想我遗漏了一些关于python变量作用域的东西。
下面是我的代码:
PRICE_RANGES = {
64:(25, 0.35),
32:(13, 0.40),
16:(7, 0.45),
8:(4, 0.5)
}
def get_order_total(quantity):
global PRICE_RANGES
_total = 0
_i = PRICE_RANGES.iterkeys()
def recurse(_i):
try:
key = _i.next()
if quantity % key != quantity:
_total += PRICE_RANGES[key][0]
return recurse(_i)
except StopIteration:
return (key, quantity % key)
res = recurse(_i)
我得到了
“未定义全局名称'_total‘”
我知道问题出在_total
赋值上,但我不明白为什么。recurse()
不应该访问父函数的变量吗?
谁能给我解释一下我在python变量作用域中遗漏了什么?
发布于 2011-03-07 19:22:35
当我运行你的代码时,我得到这个错误:
UnboundLocalError: local variable '_total' referenced before assignment
这个问题是由下面这一行引起的:
_total += PRICE_RANGES[key][0]
The documentation about Scopes and Namespaces这样说:
的一个特殊怪癖是--如果没有有效的
global
语句--名称的赋值总是进入最里面的作用域。赋值不复制数据-它们只是将名称绑定到对象。
因此,由于这句话实际上是在说:
_total = _total + PRICE_RANGES[key][0]
它在recurse()
的名称空间中创建_total
。由于_total
是新的且未赋值,因此您不能在加法中使用它。
发布于 2011-11-18 14:54:17
在Python3中,可以使用nonlocal
statement访问非本地、非全局作用域。
nonlocal
语句使变量定义绑定到以前在最近的作用域中创建的变量。这里有一些例子来说明:
def sum_list_items(_list):
total = 0
def do_the_sum(_list):
for i in _list:
total += i
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
上面的示例将失败,并显示错误:UnboundLocalError: local variable 'total' referenced before assignment
使用nonlocal
,我们可以让代码正常工作:
def sum_list_items(_list):
total = 0
def do_the_sum(_list):
# Define the total variable as non-local, causing it to bind
# to the nearest non-global variable also called total.
nonlocal total
for i in _list:
total += i
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
但是“最近”是什么意思呢?下面是另一个示例:
def sum_list_items(_list):
total = 0
def do_the_sum(_list):
# The nonlocal total binds to this variable.
total = 0
def do_core_computations(_list):
# Define the total variable as non-local, causing it to bind
# to the nearest non-global variable also called total.
nonlocal total
for i in _list:
total += i
do_core_computations(_list)
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
在上面的示例中,total
将绑定到do_the_sum
函数内部定义的变量,而不是sum_list_items
函数中定义的外部变量,因此代码将返回0
。
def sum_list_items(_list):
# The nonlocal total binds to this variable.
total = 0
def do_the_sum(_list):
def do_core_computations(_list):
# Define the total variable as non-local, causing it to bind
# to the nearest non-global variable also called total.
nonlocal total
for i in _list:
total += i
do_core_computations(_list)
do_the_sum(_list)
return total
sum_list_items([1, 2, 3])
在上面的示例中,非本地赋值在找到sum_list_items
的本地变量total
之前遍历了两级。
发布于 2012-11-08 04:08:03
这里有一个插图,说明了David答案的本质。
def outer():
a = 0
b = 1
def inner():
print a
print b
#b = 4
inner()
outer()
注释掉b = 4
语句后,此代码输出0 1
,正如您所期望的那样。
但是,如果您在print b
行取消对该行的注释,则会得到错误
UnboundLocalError: local variable 'b' referenced before assignment
似乎很神秘的是,b = 4
的出现可能会以某种方式让b
消失在它之前的行上。但David引用的文本解释了原因:在静态分析期间,解释器确定b在inner
中被赋值,因此它是inner
的局部变量。print行尝试在分配b
之前在该内部作用域中打印它。
https://stackoverflow.com/questions/5218895
复制相似问题