首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Python嵌套函数变量作用域

Python嵌套函数变量作用域
EN

Stack Overflow用户
提问于 2011-03-07 19:05:45
回答 10查看 108.7K关注 0票数 142

我已经阅读了关于这个主题的几乎所有其他问题,但我的代码仍然无法工作。

我想我遗漏了一些关于python变量作用域的东西。

下面是我的代码:

代码语言:javascript
复制
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变量作用域中遗漏了什么?

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2011-03-07 19:22:35

当我运行你的代码时,我得到这个错误:

代码语言:javascript
复制
UnboundLocalError: local variable '_total' referenced before assignment

这个问题是由下面这一行引起的:

代码语言:javascript
复制
_total += PRICE_RANGES[key][0]

The documentation about Scopes and Namespaces这样说:

的一个特殊怪癖是--如果没有有效的global语句--名称的赋值总是进入最里面的作用域。赋值不复制数据-它们只是将名称绑定到对象。

因此,由于这句话实际上是在说:

代码语言:javascript
复制
_total = _total + PRICE_RANGES[key][0]

它在recurse()的名称空间中创建_total。由于_total是新的且未赋值,因此您不能在加法中使用它。

票数 70
EN

Stack Overflow用户

发布于 2011-11-18 14:54:17

在Python3中,可以使用nonlocal statement访问非本地、非全局作用域。

nonlocal语句使变量定义绑定到以前在最近的作用域中创建的变量。这里有一些例子来说明:

代码语言:javascript
复制
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,我们可以让代码正常工作:

代码语言:javascript
复制
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])

但是“最近”是什么意思呢?下面是另一个示例:

代码语言:javascript
复制
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

代码语言:javascript
复制
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之前遍历了两级。

票数 266
EN

Stack Overflow用户

发布于 2012-11-08 04:08:03

这里有一个插图,说明了David答案的本质。

代码语言:javascript
复制
def outer():
    a = 0
    b = 1

    def inner():
        print a
        print b
        #b = 4

    inner()

outer()

注释掉b = 4语句后,此代码输出0 1,正如您所期望的那样。

但是,如果您在print b行取消对该行的注释,则会得到错误

代码语言:javascript
复制
UnboundLocalError: local variable 'b' referenced before assignment

似乎很神秘的是,b = 4的出现可能会以某种方式让b消失在它之前的行上。但David引用的文本解释了原因:在静态分析期间,解释器确定b在inner中被赋值,因此它是inner的局部变量。print行尝试在分配b之前在该内部作用域中打印它。

票数 182
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5218895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档