鱼C论坛

 找回密码
 立即注册
查看: 1470|回复: 14

[已解决]第20讲 第3题 关于代码A和代码B

[复制链接]
发表于 2017-7-26 14:48:43 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码A
def outside():
    var = 5
    def inside():
        var = 3
        print(var)
        
    inside()

outside()

代码B
def outside():
    var = 5
    def inside():
        print(var)
        var = 3
        
    inside()
outside()

为什么代码A正常     代码B报错

答案是outside()里面有一个var变量,内嵌函数inside()也有一个同名变量,Python为了保护变量的作用域,故将outside()的var变量屏蔽起来,因此此时是无法访问到外层的var变量

我的理解是,代码A中内嵌函数inside()中重新定义一个同名的var变量并赋值(区别与外部函数outside()中的var变量),然后打印该变量的值。代码B中内嵌函数inside()先打印外部函数outside()中的var变量的值(内部函数是可以访问外部函数中的变量),然后重新定义一个同名的var变量并赋值。为什么不能这样理解呢?
最佳答案
2017-7-26 19:01:52
tester_cui 发表于 2017-7-26 18:57
恩  这里print(var) 是访问outside()外部函数的var变量,按你的解释,接下来的那句var = 3是要是修改var ...

因为你先访问了,所以这个变量名的作用域就大于这个函数了,你就不能重新再定义一个同样的变量名。
如果你先定义var=3 那么var就覆盖掉外面var=5,这样就是在函数内部新定义的变量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-7-26 15:50:19 | 显示全部楼层
你的理解就有错误了啊。

B中先使用了print(var) 此时var就是一个外部的变量, 因此只能访问不能修改
所以var=3 就报错了。
如果你去掉var=3  
那么代码就又正常了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 17:43:54 | 显示全部楼层
既然是报错,肯定有报错的内容,看看返回的错误内容是什么。还有就是这个语言是不是没有大括号之类的东西?全靠缩进来判断么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 18:31:14 | 显示全部楼层
首先我要告诉你的是:每个函数里面的变量都是局部的。
我把代码改下,方便你理解:
  1. 代码A
  2. def outside():
  3.     var = 5
  4.     def inside():
  5.         a = 3 #定义a,赋值3
  6.         print(a)
  7.         
  8.     inside()

  9. outside()

  10. 代码B
  11. def outside():
  12.     var = 5
  13.     def inside():
  14.         print(a) #这个a还没有定义,就使用了
  15.         a = 3
  16.         
  17.     inside()
  18. outside()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-26 18:51:05 | 显示全部楼层
ba21 发表于 2017-7-26 18:31
首先我要告诉你的是:每个函数里面的变量都是局部的。
我把代码改下,方便你理解:

题目中的代码B  print(var)此时不是可以访问outside()外部函数中的var变量么?虽然inside()内部函数没有定义var变量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-26 18:52:09 | 显示全部楼层
人之初 发表于 2017-7-26 17:43
既然是报错,肯定有报错的内容,看看返回的错误内容是什么。还有就是这个语言是不是没有大括号之类的东西? ...

python里面没有大括号 , 是靠缩进来确定范围
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 18:54:40 | 显示全部楼层
yongxi 发表于 2017-7-26 15:50
你的理解就有错误了啊。

B中先使用了print(var) 此时var就是一个外部的变量, 因此只能访问不能修改

你跑马测试通过了吗?我用的是c语言,也是实现这个的,编译直接报错,说每个未声明标识符只在其出现的每个函数中报告一次。
简单来讲就是未声明先使用了,外部函数中的变量的作用域只限于本函数,内函数无法调用,而内函数未声明变量就直接调用,所以报错。还是作用域在作怪
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 18:57:27 | 显示全部楼层
人之初 发表于 2017-7-26 18:54
你跑马测试通过了吗?我用的是c语言,也是实现这个的,编译直接报错,说每个未声明标识符只在其出现的每个 ...

python3.4跑过了。
你在内部可以直接访问外部的函数,但是不能修改。
如果你要修改,就只能声明不是局部变量,用global

B中 已经先访问了var,那么var的作用域就是在外部,你在函数内部怎么能直接修改var的值呢?
所以var=3就是错误的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-26 18:57:28 | 显示全部楼层
yongxi 发表于 2017-7-26 15:50
你的理解就有错误了啊。

B中先使用了print(var) 此时var就是一个外部的变量, 因此只能访问不能修改

恩  这里print(var) 是访问outside()外部函数的var变量,按你的解释,接下来的那句var = 3是要是修改var变量,此时肯定是不能修改外部函数的变量的,但我的理解错在此时是重新在内部函数中定义了一个同名的var的变量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 18:57:44 | 显示全部楼层
tester_cui 发表于 2017-7-26 18:51
题目中的代码B  print(var)此时不是可以访问outside()外部函数中的var变量么?虽然inside()内部函数没有 ...

听哪位大神说的???我敢肯定小甲鱼一定没有这么说过

nonlocal关键字:(用于在内部函数中修改外部函部的变量)
>>> def fun1():
        x=5
        def fun2():
                nonlocal x
                x*=x
                retrun x;
        return fun2()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 18:59:02 | 显示全部楼层
tester_cui 发表于 2017-7-26 18:52
python里面没有大括号 , 是靠缩进来确定范围

我正在学c。python还不太懂,第一次看到代码还以为是书写不规范呢,尴尬了……
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-26 18:59:37 | 显示全部楼层
ba21 发表于 2017-7-26 18:57
听哪位大神说的???我敢肯定小甲鱼一定没有这么说过

nonlocal关键字:(用于在内部函数中修改外部函 ...

内部函数 是 可以访问 外部函数的变量的 ,但是不能修改
如果一定要修改 ,就使用关键字 nonlocal


是这样的吧!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 19:01:52 | 显示全部楼层    本楼为最佳答案   
tester_cui 发表于 2017-7-26 18:57
恩  这里print(var) 是访问outside()外部函数的var变量,按你的解释,接下来的那句var = 3是要是修改var ...

因为你先访问了,所以这个变量名的作用域就大于这个函数了,你就不能重新再定义一个同样的变量名。
如果你先定义var=3 那么var就覆盖掉外面var=5,这样就是在函数内部新定义的变量
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-7-26 19:07:26 | 显示全部楼层
yongxi 发表于 2017-7-26 19:01
因为你先访问了,所以这个变量名的作用域就大于这个函数了,你就不能重新再定义一个同样的变量名。
如果 ...

(⊙o⊙)哦    这么说  我就理解了   非常感谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-7-26 19:18:53 | 显示全部楼层
tester_cui 发表于 2017-7-26 18:59
内部函数 是 可以访问 外部函数的变量的 ,但是不能修改
如果一定要修改 ,就使用关键字 nonlocal

不好意思,我理解错误了。是能访问,不能修改。修改才加nonlocal

之前哪个
print(var)
var = 3
放一起编译器出才出错,因为后面这句var = 3定义要放在前面
var = 3
print(var)

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 18:32

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表