鱼C论坛

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

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

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

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

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

x
本帖最后由 深山小兽 于 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[i] = "红球是: ", 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()
最佳答案
2020-10-28 16:53:32
深山小兽 发表于 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()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

不知道你是不是这个意思。
想知道小甲鱼最近在做啥?请访问 -> 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之间来回使用出现障碍。我感觉需要装饰器来解决,也不确定装饰器能不能起作用,不过我还没学到这里来。所以这代码写不下去了。
想知道小甲鱼最近在做啥?请访问 -> 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行)

修改建议:统一一下,要么都用字符串,要么都用数字。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-10-28 16:37:17 | 显示全部楼层
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[i] = "红球是: ", 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)两个函数合并成一个呢?因为都是判断球的颜色,我现在这样有设置多余的函数的嫌疑。想了半天还是不会。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-10-28 16:53:32 | 显示全部楼层    本楼为最佳答案   
深山小兽 发表于 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()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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

谢谢,我还是底子太薄,想复用就是没有想到方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-18 04:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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