函数变量的使用范围如何改变。具体如下问:
本帖最后由 深山小兽 于 2020-10-28 09:10 编辑函数1里的red_choose怎么弄才能在函数2,3互通使用。下面代码有错误,无法互通。每次执行 都在句子1卡住。
def user_choose():
global i
global num_dict
print("欢迎进入自选号码菜单!\n")
print("如果想返回上级菜单请输入R!")
red_list_choose = []
blue_list_choose = []
j = 0
def isdigited(red_choose,scoped): # 函数1
nonlocal j
nonlocal red_list_choose
nonlocal blue_list_choose
if red_choose.isdigit():
red_choose = int(red_choose)
red_list_choose.append(red_choose)
scoped()
def red_scoped(): # 函数2
nonlocal j
nonlocal red_choose
nonlocal red_list_choose
nonlocal blue_list_choose
if red_choose not in range(1, 33):
red_list_choose.pop()
red_choose_s = input("您输入的红球超出范围,请重新输入!") # 句子1
isdigited(red_choose_s, red_scoped)
def blue_scoped(): # 函数3
nonlocal j
nonlocal blue_choose
nonlocal red_list_choose
nonlocal blue_list_choose
if blue_choose not in range(1, 17):
blue_list_choose.pop()
blue_choose = input("您输入的号码超出范围,请重新输入!")
isdigited(blue_choose, blue_scoped)
while True:
red_choose = input("请您选择红色号码,请在1到32之间选择:")
isdigited(red_choose, red_scoped)
while red_list_choose.count(red_choose) == 2:
red_list_choose.pop()
red_choose = input("您输入的号码之前已经存在,号码重复,请重新输入:")
isdigited(red_choose, red_scoped)
if len(red_list_choose) == 5:
while True:
blue_choose = input("您已经选择五个红色号码,请在1到16之间选择蓝球:")
isdigited(blue_choose, blue_scoped)
while blue_list_choose.count(blue_choose) == 2:
blue_list_choose.pop()
blue_choose = input("您输入的蓝球号码重复,请重新输入:")
isdigited(blue_choose, blue_scoped)
blue_list_choose.append(blue_choose)
if len(blue_list_choose) == 2:
i += 1
j += 1
# 复习列表推导式 red_list_choose_d = ["%-2d" % x for x in red_list_choose]
# 复习列表推导式 blue_list_choose_d = ["%-2d" % y for y in blue_list_choose]
str_red = []
str_blue = []
for each in red_list_choose:# 格式化红球
each = str(each)
if len(each) == 1:
each = '0' + each
str_red.append(each)
for each in blue_list_choose:# 格式化蓝球
each = str(each)
if len(each) == 1:
each = '0' + each
str_blue.append(each)
num_dict = "红球是: ", red_list_choose, "蓝球是: ", blue_list_choose
red_list_choose = []
blue_list_choose = []
print("您已经自选了%-2d组号码,请自选您的第%-2d组号码!" % (j, j + 1))
break
if blue_choose in ["r", "R"]:
main()
if red_choose in ["r", "R"]:
main()
user_choose()
把该变量定义在与函数2、3同级,在函数2、3内部用nonlocal关键字声明该变量,只要其中一个函数对它进行修改,另一个函数就能访问到修改结果。
还有一个方法,把该变量储存在一个列表内,函数2或3用列表的方法对列表内的值更改,另一个函数也能访问到更改后的值,无需nonlocal关键字。
不知道你是不是这个意思。 本帖最后由 深山小兽 于 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之间来回使用出现障碍。我感觉需要装饰器来解决,也不确定装饰器能不能起作用,不过我还没学到这里来。所以这代码写不下去了。 本帖最后由 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行)
修改建议:统一一下,要么都用字符串,要么都用数字。 sunrise085 发表于 2020-10-28 15:36
你的想法没问题。用nonlocal是可以实现的。
但是你的程序有一些问题,因为你你没给全部程序,不太好验 ...
def user_choose():
global i
global num_dict
print("欢迎进入自选号码菜单!\n")
print("如果想返回上级菜单请输入R!")
red_list_choose = []
blue_list_choose = []
j = 0
def red_isdigit(scoped):
nonlocal j
nonlocal red_choose
nonlocal red_list_choose
if red_choose.isdigit():
red_choose = int(red_choose)
red_list_choose.append(red_choose)
scoped()
def red_scoped():
nonlocal j
nonlocal red_choose
nonlocal red_list_choose
if red_choose not in range(1, 33):
red_list_choose.pop()
print("您输入的红球超出范围,请重新输入:")
red_choose = input()
red_isdigit(red_scoped)
def blue_isdigit(scoped):
nonlocal j
nonlocal blue_choose
nonlocal blue_list_choose
if blue_choose.isdigit():
blue_choose = int(blue_choose)
blue_list_choose.append(blue_choose)
scoped()
def blue_scoped():
nonlocal j
nonlocal blue_choose
nonlocal blue_list_choose
if blue_choose not in range(1, 17):
blue_list_choose.pop()
blue_choose = input("您输入的号码超出范围,请重新输入!")
blue_isdigit(blue_scoped)
while True:
red_choose = input("请您选择红色号码,请在1到32之间选择:")
red_isdigit(red_scoped)
while red_list_choose.count(red_choose) == 2:
red_list_choose.pop()
red_choose = input("您输入的号码之前已经存在,号码重复,请重新输入:")
red_isdigit(red_scoped)
if len(red_list_choose) == 5:
while True:
blue_choose = input("您已经选择五个红色号码,请在1到16之间选择蓝球:")
blue_isdigit(blue_scoped)
while blue_list_choose.count(blue_choose) == 2:
blue_list_choose.pop()
blue_choose = input("您输入的蓝球号码重复,请重新输入:")
blue_isdigit(blue_scoped)
blue_list_choose.append(blue_choose)
if len(blue_list_choose) == 2:
i += 1
j += 1
# 复习列表推导式 red_list_choose_d = ["%-2d" % x for x in red_list_choose]
# 复习列表推导式 blue_list_choose_d = ["%-2d" % y for y in blue_list_choose]
str_red = []
str_blue = []
for each in red_list_choose:# 格式化红球
each = str(each)
if len(each) == 1:
each = '0' + each
str_red.append(each)
for each in blue_list_choose:# 格式化蓝球
each = str(each)
if len(each) == 1:
each = '0' + each
str_blue.append(each)
num_dict = "红球是: ", red_list_choose, "蓝球是: ", blue_list_choose
red_list_choose = []
blue_list_choose = []
print("您已经自选了%-2d组号码,请自选您的第%-2d组号码!" % (j, j + 1))
break
if blue_choose in ["r", "R"]:
main()
if red_choose in ["r", "R"]:
main()
谢谢你,这里修改了一下是能运行了。但是还想问一下如何把这里的red_isdigit(scoped) 和 blue_isdigit(scoped)两个函数合并成一个呢?因为都是判断球的颜色,我现在这样有设置多余的函数的嫌疑。想了半天还是不会。 深山小兽 发表于 2020-10-28 16:37
谢谢你,这里修改了一下是能运行了。但是还想问一下如何把这里的red_isdigit(scoped) 和 blue_is ...
加个参数就可以了。调用的时候给出flag,需要判断红球的时候这个参数flag给成True,需要判断蓝球的时候给成False。其实你的函数2和函数3也可以这样写。代码复用,才是编程精髓
def isdigited(flag,scoped): # 函数1
nonlocal j
nonlocal red_list_choose
nonlocal blue_list_choose
nonlocal red_choose
nonlocal blue_choose
if flag:#flag为True的时候是针对红球的,否则是针对蓝球的
if red_choose.isdigit():
red_list_choose.append(red_choose)
scoped()
else:
if blue_choose.isdigit():
blue_list_choose.append(blue_choose)
scoped()
sunrise085 发表于 2020-10-28 16:53
加个参数就可以了。调用的时候给出flag,需要判断红球的时候这个参数flag给成True,需要判断蓝球的时候给 ...
谢谢,我还是底子太薄,想复用就是没有想到方法。
页:
[1]