从父函数分配给变量:“分配前引用的局部变量"; [英] Assigning to variable from parent function: "Local variable referenced before assignment"

查看:36
本文介绍了从父函数分配给变量:“分配前引用的局部变量";的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于以下 Python 2.7 代码:

For the following Python 2.7 code:

#!/usr/bin/python

def funcA():
   print "funcA"
   c = 0 
   def funcB():
      c += 3
      print "funcB", c

   def funcC():
      print "funcC", c

   print "c", c
   funcB()
   c += 2
   funcC()
   c += 2
   funcB()
   c += 2
   funcC()
   print "end"

funcA()

我收到以下错误:

File "./a.py", line 9, in funcB
    c += 3
UnboundLocalError: local variable 'c' referenced before assignment

但是当我注释掉 funcB 中的 c += 3 行时,我得到以下输出:

But when I comment out the line c += 3 in funcB, I get the following output:

funcA
c 0
funcB 0
funcC 2
funcB 4
funcC 6
end

不是在 funcB 中的 +== 中的 = 两种情况下都可以访问 c>funcC?为什么它不为一个抛出错误而另一个不抛出错误?

Isn't c being accessed in both cases of += in funcB and = in funcC? Why doesn't it throw error for one but not for the other?

我没有选择让 c 成为一个全局变量,然后在 funcB 中声明 global c.无论如何,重点不是让 cfuncB 中递增,而是为什么它会为 funcB 而不是 funcC 抛出错误> 而两者都在访问一个局部变量或全局变量.

I don't have a choice of making c a global variable and then declaring global c in funcB. Anyway, the point is not to get c incremented in funcB but why it's throwing error for funcB and not for funcC while both are accessing a variable that's either local or global.

推荐答案

您在这里看到的是访问和分配变量之间的区别.在 Python 2.x 中,您只能分配给最内层作用域或全局作用域中的变量(后者是通过使用 global 语句完成的).您可以访问任何封闭范围内的变量,但不能访问封闭范围内的变量,然后在最内层或全局范围内对其进行赋值.

What you are seeing here is the difference between accessing and assigning variables. In Python 2.x you can only assign to variables in the innermost scope or the global scope (the latter is done by using the global statement). You can access variables in any enclosing scope, but you cannot access a variable in an enclosing scope and then assign to it in the innermost or global scope.

这意味着如果在函数内部对名称进行了任何赋值,那么在访问名称之前,该名称必须已经在最内部的作用域中定义(除非使用了 global 语句).在您的代码中,c += 3 行本质上等同于以下内容:

What this means is that if there is any assignment to a name inside of a function, that name must already be defined in the innermost scope before the name is accessed (unless the global statement was used). In your code the line c += 3 is essentially equivalent to the following:

tmp = c
c = tmp + 3

因为函数中有对 c 的赋值,在该函数中 c 的每个其他出现只会在 的局部范围内查找funcB.这就是您看到错误的原因,您尝试访问 c 以获取 += 的当前值,但在本地范围 c> 尚未定义.

Because there is an assignment to c in the function, every other occurrence of c in that function will only look in the local scope for funcB. This is why you see the error, you are attempting to access c to get its current value for the +=, but in the local scope c has not been defined yet.

在 Python 3 中,您可以通过使用 nonlocal语句,它允许您分配不在当前范围内但也不在全局范围内的变量.

In Python 3 you could get around this issue by using the nonlocal statement, which allows you to assign to variables that are not in the current scope, but are also not in the global scope.

你的代码看起来像这样,在 funcC 的顶部有一个类似的行:

Your code would look something like this, with a similar line at the top of funcC:

   def funcB():
      nonlocal c
      c += 3
      ...

在 Python 2.x 中,这不是一个选项,您可以更改非局部变量值的唯一方法是它是否可变.

In Python 2.x this isn't an option, and the only way you can change the value of a nonlocal variable is if it is mutable.

最简单的方法是将您的值包装在一个列表中,然后在您之前刚刚使用变量名的每个地方修改并访问该列表的第一个元素:

The simplest way to do this is to wrap your value in a list, and then modify and access the first element of that list in every place where you had previously just used the variable name:

def funcA():
   print "funcA"
   c = [0]
   def funcB():
      c[0] += 3
      print "funcB", c[0]

   def funcC():
      c[0] = 5
      print "funcC", c[0]

   print "c", c[0]
   funcB()
   funcC()
   funcB()
   funcC()
   print "end"

funcA()

...和输出:

funcA
c 0
funcB 3
funcC 5
funcB 8
funcC 5
end

这篇关于从父函数分配给变量:“分配前引用的局部变量";的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆