鱼C论坛

 找回密码
 立即注册
查看: 1670|回复: 6

[已解决]函数变量的使用范围如何改变。具体如下问:

[复制链接]
发表于 2020-10-28 09:08:12 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 深山小兽 于 2020-10-28 09:10 编辑

函数1里的red_choose怎么弄才能在函数2,3互通使用。下面代码有错误,无法互通。每次执行 都在句子1卡住。



  1. def user_choose():
  2.     global i
  3.     global num_dict



  4.     print("欢迎进入自选号码菜单!\n")
  5.     print("如果想返回上级菜单请输入R!")

  6.     red_list_choose = []
  7.     blue_list_choose = []
  8.     j = 0

  9.     def isdigited(red_choose,scoped):                                        #                 函数1
  10.         nonlocal j
  11.         nonlocal red_list_choose
  12.         nonlocal blue_list_choose
  13.         if red_choose.isdigit():
  14.             red_choose = int(red_choose)
  15.             red_list_choose.append(red_choose)
  16.             scoped()

  17.     def red_scoped():                                                                                            #               函数2
  18.         nonlocal j
  19.         nonlocal red_choose
  20.         nonlocal red_list_choose
  21.         nonlocal blue_list_choose
  22.         if red_choose not in range(1, 33):
  23.             red_list_choose.pop()
  24.             red_choose_s = input("您输入的红球超出范围,请重新输入!")                           #                      句子1
  25.             isdigited(red_choose_s, red_scoped)



  26.     def blue_scoped():                                                                              #                          函数3
  27.         nonlocal j
  28.         nonlocal blue_choose
  29.         nonlocal red_list_choose
  30.         nonlocal blue_list_choose
  31.         if blue_choose not in range(1, 17):
  32.             blue_list_choose.pop()
  33.             blue_choose = input("您输入的号码超出范围,请重新输入!")
  34.             isdigited(blue_choose, blue_scoped)

  35.     while True:
  36.         red_choose = input("请您选择红色号码,请在1到32之间选择:")
  37.         isdigited(red_choose, red_scoped)
  38.         while red_list_choose.count(red_choose) == 2:
  39.             red_list_choose.pop()
  40.             red_choose = input("您输入的号码之前已经存在,号码重复,请重新输入:")
  41.             isdigited(red_choose, red_scoped)
  42.         if len(red_list_choose) == 5:
  43.             while True:
  44.                 blue_choose = input("您已经选择五个红色号码,请在1到16之间选择蓝球:")
  45.                 isdigited(blue_choose, blue_scoped)
  46.                 while blue_list_choose.count(blue_choose) == 2:
  47.                     blue_list_choose.pop()
  48.                     blue_choose = input("您输入的蓝球号码重复,请重新输入:")
  49.                     isdigited(blue_choose, blue_scoped)
  50.                     blue_list_choose.append(blue_choose)
  51.                 if len(blue_list_choose) == 2:
  52.                     i += 1
  53.                     j += 1
  54.                     # 复习列表推导式 red_list_choose_d = ["%-2d" % x for x in red_list_choose]
  55.                     # 复习列表推导式 blue_list_choose_d = ["%-2d" % y for y in blue_list_choose]
  56.                     str_red = []
  57.                     str_blue = []
  58.                     for each in red_list_choose:  # 格式化红球
  59.                         each = str(each)
  60.                         if len(each) == 1:
  61.                             each = '0' + each
  62.                         str_red.append(each)
  63.                     for each in blue_list_choose:  # 格式化蓝球
  64.                         each = str(each)
  65.                         if len(each) == 1:
  66.                             each = '0' + each
  67.                         str_blue.append(each)
  68.                     num_dict[i] = "红球是: ", red_list_choose, "蓝球是: ", blue_list_choose
  69.                     red_list_choose = []
  70.                     blue_list_choose = []
  71.                     print("您已经自选了%-2d组号码,请自选您的第%-2d组号码!" % (j, j + 1))
  72.                     break

  73.                 if blue_choose in ["r", "R"]:
  74.                     main()
  75.         if red_choose in ["r", "R"]:
  76.             main()

  77. user_choose()
复制代码
最佳答案
2020-10-28 16:53:32
深山小兽 发表于 2020-10-28 16:37
谢谢你,这里修改了一下是能运行了。但是还想问一下如何把这里的red_isdigit(scoped) 和 blue_is ...

加个参数就可以了。调用的时候给出flag,需要判断红球的时候这个参数flag给成True,需要判断蓝球的时候给成False。其实你的函数2和函数3也可以这样写。代码复用,才是编程精髓
  1.     def isdigited(flag,scoped):                                        #                 函数1
  2.         nonlocal j
  3.         nonlocal red_list_choose
  4.         nonlocal blue_list_choose
  5.         nonlocal red_choose
  6.         nonlocal blue_choose
  7.         if flag:#flag为True的时候是针对红球的,否则是针对蓝球的
  8.             if red_choose.isdigit():
  9.                 red_list_choose.append(red_choose)
  10.                 scoped()
  11.         else:
  12.             if blue_choose.isdigit():
  13.                 blue_list_choose.append(blue_choose)
  14.                 scoped()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-10-28 10:10:15 From FishC Mobile | 显示全部楼层
把该变量定义在与函数2、3同级,在函数2、3内部用nonlocal关键字声明该变量,只要其中一个函数对它进行修改,另一个函数就能访问到修改结果。

还有一个方法,把该变量储存在一个列表内,函数2或3用列表的方法对列表内的值更改,另一个函数也能访问到更改后的值,无需nonlocal关键字。

不知道你是不是这个意思。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-28 11:35:52 | 显示全部楼层
本帖最后由 深山小兽 于 2020-10-28 11:38 编辑
hrp 发表于 2020-10-28 10:10
把该变量定义在与函数2、3同级,在函数2、3内部用nonlocal关键字声明该变量,只要其中一个函数对它进行修改 ...


我现在就是希望一个变量在几个同级别的函数里可以存储及调用,或者说通行,通用。比如我说的函数1,函数2,函数3,的red_choose,blue_choose.两个变量可以在三个函数里通行。我使用了nonlocal这个代码,但是好像没起到该有的作用,主要是在函数1到函数2,3之间来回使用出现障碍。我感觉需要装饰器来解决,也不确定装饰器能不能起作用,不过我还没学到这里来。所以这代码写不下去了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-28 15:36:16 | 显示全部楼层
本帖最后由 sunrise085 于 2020-10-28 15:45 编辑
深山小兽 发表于 2020-10-28 11:35
我现在就是希望一个变量在几个同级别的函数里可以存储及调用,或者说通行,通用。比如我说的函数1,函 ...


你的想法没问题。用nonlocal是可以实现的。
但是你的程序有一些问题,因为你你没给全部程序,不太好验证,我也就不帮你修改了,帮你指出问题,你自己尝试修改吧。

问题一、red_choose和blue_choose这两个变量想做成同一层的局部变量,那么就在里面这几个函数中都统一一下吧,否则会出错。函数2和函数3中你使用的是nonlocal,而在函数1中确实以参数的形式传进去的。这就导致在函数2/3中再次调用函数1的时候,虽然修改了red_choose或blue_choose,但是你修改的只是内部变量而非这三个函数外的red_choose或blue_choose。举个例子,比如你输入红球的时候输入34,超范围了,进入函数2会让你重新输入,你输入12,赋值给red_choose_s,进入函数1,然后再次进入函数2的时候nonlocal red_choose依然是34。。。

修改建议:函数1中red_choose不作为参数传入,与函数2一样用nonlocal,到底是在判断红球还是蓝球,可以用另外一个变量;函数2中再次输入的时候直接修改red_choose,而不是red_choose_s,函数3与函数2同步修改

问题二、你在函数1中向列表中追加的是int类型数据(20行),但是在下面while中追加的是字符串(60行),查是否重复的时候也是用的字符串(48行,56行)

修改建议:统一一下,要么都用字符串,要么都用数字。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-28 16:37:17 | 显示全部楼层
sunrise085 发表于 2020-10-28 15:36
你的想法没问题。用nonlocal是可以实现的。
但是你的程序有一些问题,因为你你没给全部程序,不太好验 ...
  1. def user_choose():
  2.     global i
  3.     global num_dict

  4.     print("欢迎进入自选号码菜单!\n")
  5.     print("如果想返回上级菜单请输入R!")

  6.     red_list_choose = []
  7.     blue_list_choose = []
  8.     j = 0

  9.     def red_isdigit(scoped):
  10.         nonlocal j
  11.         nonlocal red_choose
  12.         nonlocal red_list_choose
  13.         if red_choose.isdigit():
  14.             red_choose = int(red_choose)
  15.             red_list_choose.append(red_choose)
  16.             scoped()

  17.     def red_scoped():
  18.         nonlocal j
  19.         nonlocal red_choose
  20.         nonlocal red_list_choose
  21.         if red_choose not in range(1, 33):
  22.             red_list_choose.pop()
  23.             print("您输入的红球超出范围,请重新输入:")
  24.             red_choose = input()
  25.             red_isdigit(red_scoped)

  26.     def blue_isdigit(scoped):
  27.         nonlocal j
  28.         nonlocal blue_choose
  29.         nonlocal blue_list_choose
  30.         if blue_choose.isdigit():
  31.             blue_choose = int(blue_choose)
  32.             blue_list_choose.append(blue_choose)
  33.             scoped()

  34.     def blue_scoped():
  35.         nonlocal j
  36.         nonlocal blue_choose
  37.         nonlocal blue_list_choose
  38.         if blue_choose not in range(1, 17):
  39.             blue_list_choose.pop()
  40.             blue_choose = input("您输入的号码超出范围,请重新输入!")
  41.             blue_isdigit(blue_scoped)

  42.     while True:
  43.         red_choose = input("请您选择红色号码,请在1到32之间选择:")
  44.         red_isdigit(red_scoped)
  45.         while red_list_choose.count(red_choose) == 2:
  46.             red_list_choose.pop()
  47.             red_choose = input("您输入的号码之前已经存在,号码重复,请重新输入:")
  48.             red_isdigit(red_scoped)
  49.         if len(red_list_choose) == 5:
  50.             while True:
  51.                 blue_choose = input("您已经选择五个红色号码,请在1到16之间选择蓝球:")
  52.                 blue_isdigit(blue_scoped)
  53.                 while blue_list_choose.count(blue_choose) == 2:
  54.                     blue_list_choose.pop()
  55.                     blue_choose = input("您输入的蓝球号码重复,请重新输入:")
  56.                     blue_isdigit(blue_scoped)
  57.                     blue_list_choose.append(blue_choose)
  58.                 if len(blue_list_choose) == 2:
  59.                     i += 1
  60.                     j += 1
  61.                     # 复习列表推导式 red_list_choose_d = ["%-2d" % x for x in red_list_choose]
  62.                     # 复习列表推导式 blue_list_choose_d = ["%-2d" % y for y in blue_list_choose]
  63.                     str_red = []
  64.                     str_blue = []
  65.                     for each in red_list_choose:  # 格式化红球
  66.                         each = str(each)
  67.                         if len(each) == 1:
  68.                             each = '0' + each
  69.                         str_red.append(each)
  70.                     for each in blue_list_choose:  # 格式化蓝球
  71.                         each = str(each)
  72.                         if len(each) == 1:
  73.                             each = '0' + each
  74.                         str_blue.append(each)
  75.                     num_dict[i] = "红球是: ", red_list_choose, "蓝球是: ", blue_list_choose
  76.                     red_list_choose = []
  77.                     blue_list_choose = []
  78.                     print("您已经自选了%-2d组号码,请自选您的第%-2d组号码!" % (j, j + 1))
  79.                     break
  80.                 if blue_choose in ["r", "R"]:
  81.                     main()
  82.         if red_choose in ["r", "R"]:
  83.             main()
复制代码



谢谢你,这里修改了一下是能运行了。但是还想问一下如何把这里的red_isdigit(scoped) 和 blue_isdigit(scoped)两个函数合并成一个呢?因为都是判断球的颜色,我现在这样有设置多余的函数的嫌疑。想了半天还是不会。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-28 16:53:32 | 显示全部楼层    本楼为最佳答案   
深山小兽 发表于 2020-10-28 16:37
谢谢你,这里修改了一下是能运行了。但是还想问一下如何把这里的red_isdigit(scoped) 和 blue_is ...

加个参数就可以了。调用的时候给出flag,需要判断红球的时候这个参数flag给成True,需要判断蓝球的时候给成False。其实你的函数2和函数3也可以这样写。代码复用,才是编程精髓
  1.     def isdigited(flag,scoped):                                        #                 函数1
  2.         nonlocal j
  3.         nonlocal red_list_choose
  4.         nonlocal blue_list_choose
  5.         nonlocal red_choose
  6.         nonlocal blue_choose
  7.         if flag:#flag为True的时候是针对红球的,否则是针对蓝球的
  8.             if red_choose.isdigit():
  9.                 red_list_choose.append(red_choose)
  10.                 scoped()
  11.         else:
  12.             if blue_choose.isdigit():
  13.                 blue_list_choose.append(blue_choose)
  14.                 scoped()
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2020-10-28 17:08:07 | 显示全部楼层
sunrise085 发表于 2020-10-28 16:53
加个参数就可以了。调用的时候给出flag,需要判断红球的时候这个参数flag给成True,需要判断蓝球的时候给 ...

谢谢,我还是底子太薄,想复用就是没有想到方法。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-28 21:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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