当前位置:  开发笔记 > 编程语言 > 正文

使用其中的另一个方法更改方法内的变量

如何解决《使用其中的另一个方法更改方法内的变量》经验,为你挑选了4个好方法。

以下代码提出了UnboundLocalError:

def foo():
    i = 0
    def incr():
        i += 1
    incr()
    print(i)

foo()

有没有办法实现这个目标?



1> piglei..:

使用nonlocal声明

def foo():
    i = 0
    def incr():
        nonlocal i
        i += 1
    incr()
    print(i)

foo()

有关python 3.x中添加的新语句的更多信息,请访问https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement



2> Kevin Guan..:

你可以i像这样使用一个参数:

def foo():
    i = 0
    def incr(i):
        return i + 1
    i = incr(i)
    print(i)

foo()


很好的答案,因为这不依赖于Python 3,就像其他`非本地`解决方案一样.
名称`incr`没有很好地选择一个函数,它返回一个比它的参数更多而没有任何副作用的函数.

3> Maroun..:

见9.2.Python范围和命名空间:

如果没有global语句生效 - 名称的赋值总是进入最内层范围.

也:

global陈述可用于表明特定变量存在于全球范围内,并应在那里反弹; 该nonlocal陈述表明特定变量存在于封闭范围内,应该在那里反弹.

你有很多解决方案:

i作为参数传递✓(我会选择这个)

使用nonlocal关键字

请注意,在Python2.x中,您可以访问非局部变量,但无法更改它们.



4> Jim Fasaraki..:

人们已经回答了你的问题,但似乎没有人解决为什么会发生这种情况.

以下代码提出了一个问题 UnboundLocalError

那么,为什么呢?让我们从FAQ中引用:

当您对作用域中的变量进行赋值时,该变量将成为该作用域的局部变量,并在外部作用域中隐藏任何类似命名的变量.

在嵌套函数中,您正在与+=运算符执行赋值.这意味着i += 1将近似执行i = i + 1(从绑定的角度来看).因此i,i + 1将在本地范围内搜索表达式(因为它在赋值语句中使用)incr,因为它将无法找到它的函数,从而产生一个UnboundLocalError: reference before assignment.

有很多方法可以解决这个问题,python 3在你可以采用的方法上比python 2更优雅.

Python 3nonlocal:

这些nonlocal语句告诉Python在foo()名称引用的封闭范围内查找名称(在本例中,在函数范围内):

def foo():
    i = 0
    def incr():
        nonlocal i
        i +=1
    incr()
    print(i)

函数属性Python 2.x3.x:

请记住,函数是第一类对象,因此它们可以存储状态.使用函数属性来访问和改变函数状态,这种方法的好处是它适用于所有 pythons并且不需要global, nonlocal语句.

def foo():
    foo.i = 0
    def incr():
        foo.i +=1
    incr()
    print(foo.i)

global声明(Python的2.x,3.x):

真是最丑陋的一群,但完成了工作:

i = 0
def foo():
    def incr():
        global i
        i += 1
    incr()
    print(i)

foo()

将参数传递给函数的选项获得相同的结果,但它与在某种意义上改变封闭范围无关nonlocal,global而且更像是所呈现的函数属性.它正在函数中创建一个新的局部变量inc,然后将名称重新绑定到i,i = incr(i)但它确实完成了工作.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有