鱼C论坛

 找回密码
 立即注册
查看: 1195|回复: 12

[已解决]关于python中nonlocal的问题

[复制链接]
发表于 2018-8-28 19:09:57 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 dragon_xiao 于 2018-8-28 19:12 编辑

先举个例子:def make_counter():
    count = 0  #这里每次会重新赋值吧?
    def counter():
        nonlocal count
        count += 1
        return count
    return counter
      
def make_counter_test():
  mc = make_counter()
  print(mc())
  print(mc())
  print(mc())

make_counter_test()
输出:1
         2
         3

问题1 运行倒数第二行中 print(mc())  调用函数mc(),即调用函数 make_counter() ,这个函数一开始就 进行了 count =0 的重新赋值过程,为何最终结果是 2 ,第三次运行结果就是 3
问题2 如果count = 0 没有重新赋值,是为什么没有重新赋值?
最佳答案
2018-8-28 20:56:36
dragon_xiao 发表于 2018-8-28 20:20
我知道,会被忽略,这个结果,但是为什么会忽略他?  是什么因素导致的?

跟 nonlocal 无关,因为最终 mc = return counter。实际作用的是 counter。至于nonlocal 是把记忆留下。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-8-28 19:21:16 | 显示全部楼层
本帖最后由 claws0n 于 2018-8-28 19:22 编辑

count 是定义在 make_counter() 内部,但是 nonlocal count 却是定义在 counter() 内部。因此 nonlocal count 的作用域比 count 的作用域小,所以 count 是影响不了 nonlocal count 的。

全局变量的作用域最大,是因为它可以受到任何地方的作用。作用域越小,反而越隐秘。
counter 会一直累加是因为 nonlocal 的修饰使得该变量的数据被保留
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 19:21:23 | 显示全部楼层
你先在命令行敲mc你就知道mc其实是make_counter下的counter函数地址接口,而且counter=0只是在你赋值mc = make_counter() 才运行
其他时候只运行了mc(),使counter分别+1


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 19:39:30 | 显示全部楼层
塔利班 发表于 2018-8-28 19:21
你先在命令行敲mc你就知道mc其实是make_counter下的counter函数地址接口,而且counter=0只是在你赋值mc = m ...

请问,你说的敲mc() 就知道函数地址接口,怎么显示? IDLE 肯定报错NameError: name 'mc' is not defined。你说的counter = 0 这个赋值过程,为什么不是函数运行就执行的代码?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 19:40:56 | 显示全部楼层
你在命令行里敲啊,按你的代码顺序敲进去
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 19:41:44 | 显示全部楼层
本帖最后由 dragon_xiao 于 2018-8-28 19:43 编辑
claws0n 发表于 2018-8-28 19:21
count 是定义在 make_counter() 内部,但是 nonlocal count 却是定义在 counter() 内部。因此 nonlocal cou ...


请问,在第二句 print(mc()) 中,是会运行make_counter() 函数吧? 这里的count = 0 是不会被赋值成功吗?还是因为nonlocal 的原因保护了原来变量count 中的数据,而不参与赋值 还是什么意思呢?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 19:42:05 | 显示全部楼层
塔利班 发表于 2018-8-28 19:40
你在命令行里敲啊,按你的代码顺序敲进去

当然你的make_counter_test()没必要定义成一个函数,要每句敲出来
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 19:54:24 | 显示全部楼层
dragon_xiao 发表于 2018-8-28 19:41
请问,在第二句 print(mc()) 中,是会运行make_counter() 函数吧? 这里的count = 0 是不会被赋值成功 ...
  1. def make_counter():
  2.     count = 0
  3.     print('make_counter---',count)
  4.     def counter():
  5.         nonlocal count
  6.         count += 1
  7.         print('counter---',count)
  8.         return count
  9.     return counter
  10.       
  11. mc = make_counter()
  12. print(mc())
  13. print(mc())
  14. print(mc())
复制代码
  1. make_counter--- 0
  2. counter--- 1
  3. 1
  4. counter--- 2
  5. 2
  6. counter--- 3
  7. 3
复制代码

mc = make_counter(),当然是咯
nonlocal count 之前找到一个 count,先用它的值初始化,随后直接把它忽略了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 20:03:25 | 显示全部楼层
塔利班 发表于 2018-8-28 19:42
当然你的make_counter_test()没必要定义成一个函数,要每句敲出来

你说的很对,counter=0只是在赋值mc = make_counter() 才运行。,print(mc())时,至运行了counter +1,但是我理解不了为什么python直接跳过了 那一句代码的赋值运算?

                               
登录/注册后可看大图
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 20:08:03 | 显示全部楼层
dragon_xiao 发表于 2018-8-28 20:03
你说的很对,counter=0只是在赋值mc = make_counter() 才运行。,print(mc())时,至运行了counter +1,但 ...

因为mc是make_counter下的counter函数地址接口,之前也说了,counter=0这部分在make_counter()里
但是不在counter()函数里
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 20:20:55 | 显示全部楼层
claws0n 发表于 2018-8-28 19:54
mc = make_counter(),当然是咯
nonlocal count 之前找到一个 count,先用它的值初始化,随后直接把 ...

我知道,会被忽略,这个结果,但是为什么会忽略他?  是什么因素导致的?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-8-28 20:56:36 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
dragon_xiao 发表于 2018-8-28 20:20
我知道,会被忽略,这个结果,但是为什么会忽略他?  是什么因素导致的?

跟 nonlocal 无关,因为最终 mc = return counter。实际作用的是 counter。至于nonlocal 是把记忆留下。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-8-28 21:25:27 | 显示全部楼层
塔利班 发表于 2018-8-28 20:08
因为mc是make_counter下的counter函数地址接口,之前也说了,counter=0这部分在make_counter()里
但是不 ...

非常感谢你的帮助
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-11-7 03:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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