为什么这段代码有效:
var = 0
def func(num):
print num
var = 1
if num != 0:
func(num-1)
func(10)
但这个代码会报 "本地变量 'var' 在赋值前被引用" 的错误:
var = 0
def func(num):
print num
var = var
if num != 0:
func(num-1)
func(10)
为什么这段代码有效:
var = 0
def func(num):
print num
var = 1
if num != 0:
func(num-1)
func(10)
但这个代码会报 "本地变量 'var' 在赋值前被引用" 的错误:
var = 0
def func(num):
print num
var = var
if num != 0:
func(num-1)
func(10)
因为在第一段代码中,您创建了一个局部变量var
并使用了它的值,而在第二段代码中,您正在使用局部变量var
,但没有定义它。
因此,如果您想让您的第二个函数工作,您需要声明:
global var
var
之前的函数中。def func(num):
print num
var = 1 <-- # You create a local variable
if num != 0:
func(num-1)
在这段代码中:
def func(num):
print num
var = var <--- # You are using the local variable on RHS without defining it
if num != 0:
func(num-1)
更新: -
然而,根据@Tim的评论,您不应在函数内部使用global
变量。相反,在使用它之前定义您的变量,以在local scope
中使用它。一般来说,您应该尝试将变量的作用域限制为local
,甚至在local
命名空间中也要limit
局部变量的作用域,因为这样您的代码将更易于理解。
您增加变量作用域的程度越大,就越有可能被外部来源使用,而这并不需要使用它。
var = ...
,那么“var”这个名称将被视为整个函数的本地变量,而不管该赋值发生在哪里。这意味着函数中所有var
的出现都将在本地作用域中解析,因此var = var
右侧的表达式在赋值前引用了一个未初始化的变量var
,导致了"referenced before assignment"错误。请注意,html标签已保留。func
会成为var
的闭包,而var = var
这一行会创建一个函数局部变量var
,并将其赋值为模块级别的var
的值。你回答中的“在函数的任何地方”听起来像是魔法。这真的是实际原因吗? - Kirk Strauserco_varnames
属性中)。这导致(对我来说!)有趣的情况,比如 def foo(): var = var
无法工作,但是 def foo(): exec('var = var')
却非常好用。我认为这更像是优化通过的实现细节,而不是语言本身的特性。 - Kirk Strauserexec
时,变量在编译时不存在(或者说,它的“编译时间”是在exec
运行时而不是在定义foo
时)。你也可以通过类似的方式“规避”这个问题,比如def foo(): locals()['var'] = var
,但它仍然不会使规则失效。 - abarnert在不声明全局变量的情况下,你可以读取全局变量。但是如果要写入全局变量,你需要声明它为全局变量。
var
,因为他有一个与之重名的本地变量。 - abarnertvar
,这是全局的(在函数外定义的变量被明确地视为全局)。var = 0
def func(num):
print num
func.var = var # func.var is referring the local
# variable var inside the function func
if num != 0:
func(num-1)
func(10)
def runscan(self):
p = os.popen('LD_PRELOAD=/usr/libv4l/v4l1compat.so zbarcam
/dev/video0','r')
def input(self):
self.entryc.insert(END, code)
var = 0
def func(num):
print num
global var
var = 1
if num != 0:
func(num-1)
print var # 0
func(2)
print var # 1