为了账号安全,请及时绑定邮箱和手机立即绑定

从父函数赋值给变量:“赋值前引用的局部变量”

从父函数赋值给变量:“赋值前引用的局部变量”

墨色风雨 2019-08-05 14:21:26
从父函数赋值给变量:“赋值前引用的局部变量”对于以下Python 2.7代码:#!/usr/bin/pythondef 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 += 3UnboundLocalError: local variable 'c' referenced before assignment但是,当我注释掉该行c += 3中funcB,我得到以下的输出:funcAc 0funcB 0funcC 2funcB 4funcC 6endc在+=in funcB和=in 两种情况下都没有访问funcC?为什么不为一个而不是另一个抛出错误?我没有做一个选择c一个全局变量,然后宣布global c在funcB。无论如何,关键不是要c增加,funcB而是为什么它会抛出错误,funcB而不是因为funcC它们都在访问本地或全局的变量。
查看完整描述

3 回答

?
holdtom

TA贡献1805条经验 获得超10个赞


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


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


tmp = c

c = tmp + 3

因为c函数中有赋值,所以该函数中的每个其他实例c都只会查找本地范围funcB。这就是为什么你看到错误,你试图c获取它的当前值+=,但是在本地范围内c还没有定义。


在Python 3中,您可以通过使用非本地语句来解决此问题,该语句允许您分配不在当前范围内但不在全局范围内的变量。


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


   def funcB():

      nonlocal c

      c += 3

      ...

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


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


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


查看完整回答
反对 回复 2019-08-05
?
哔哔one

TA贡献1854条经验 获得超8个赞

在funcB中的'+ ='和funcC中的'='都不能访问'c'吗?

不,funcC制作一个新变量,也称为c=在这方面是不同的+=

要获得您(可能)想要的行为,请将变量包装在单个元素列表中:

def outer():
    c = [0]
    def inner():
        c[0] = 3
    inner()
    print c[0]

将打印3

编辑:你想要c作为一个参数传递。Python 2没有其他方法,AFAIK,以获得所需的行为。Python 3 nonlocal为这些案例引入了关键字。


查看完整回答
反对 回复 2019-08-05
?
一只萌萌小番薯

TA贡献1795条经验 获得超7个赞

1)在funcB和in c中的两种情况下都没有被访问?+==funcC

不,因为c += 3和以下一样:

c = c + 3
    ^
    |and funcB does not know what this c is

2)我没有做的一个选择c一个全局变量,然后宣布global cfuncB

请不要这样做,只需更改:

def funcB():

有:

def funcB(c):

funcB(c)在稍后的代码中调用。

注意:您还应该定义funcBfuncC外部的cosiderfuncA


查看完整回答
反对 回复 2019-08-05
  • 3 回答
  • 0 关注
  • 813 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信