鱼C论坛

 找回密码
 立即注册
查看: 8120|回复: 24

[知识点备忘] 第045讲:函数(V)- 闭包

[复制链接]
发表于 2021-12-31 22:26:32 | 显示全部楼层 |阅读模式
购买主题 已有 25 人购买  本主题需向作者支付 5 鱼币 才能浏览
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-1-4 11:17:30 | 显示全部楼层
嵌套函数的外层作用域会通过某种形式保存下来,“闭包”应运而生:在一个函数内部中,对外部作用域的变量进行引用,并且一般内部函数作为外部函数的返回值,那么内部函数就被认为是闭包。闭包又称工厂函数,通俗地说就是“来料加工,批量生产”;由于参数不同,得到了不同的“生产线”。利用闭包的特性,使用nonlocal语句可以实现带有记忆功能的函数,十分有趣!闭包可应用于游戏开发,如实现游戏角色的移动,保护角色移动位置,不被其他函数轻易修改。由此可见,任何存在的事物,必有其存在的价值和意义!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 5 反对 0

使用道具 举报

发表于 2022-2-13 20:18:36 | 显示全部楼层
闭包会被释放吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2022-5-2 17:44:19 | 显示全部楼层
origin = (0, 0) # 定义原点
legal_x = [-100, 100] # 限定X轴的移动范围
legal_y = [-100, 100] # 限定y轴的移动范围

def create(pos_x=0, pos_y=0):
    def moving(direction, step): # 定义方向和步数,
        nonlocal pos_x, pos_y
        new_x = pos_x + direction[0] * step
        new_y = pos_y + direction[1] * step

        if new_x < legal_x[0]:
            pos_x = legal_x[0] - (new_x - legal_x[0]) # 小于x轴范围时
        elif new_x > legal_x[1]:
            pos_x = legal_x[1] - (new_x - legal_x[1]) # 大于x轴范围时
        else:
            pos_x = new_x

        if new_y < legal_y[0]:
            pos_y = legal_y[0] - (new_y - legal_y[0]) # 小于y轴范围时
        elif new_y > legal_y[1]:
            pos_y = legal_y[1] - (new_y - legal_y[1]) # 大于y轴范围时
        else:
            pos_y = new_y

        return pos_x, pos_y

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

使用道具 举报

发表于 2022-5-2 17:45:40 | 显示全部楼层

接下来输入方向位置就可以玩了:
move = create()
print("准备移动,现在的位置为:", move([0, 0], 0))
>>>
准备移动,现在的位置为: (0, 0)

print("开始移动,移动后的位置为:", move([0, 1], 10))
>>>
开始移动,移动后的位置为: (0, 10)

print("开始移动,移动后的位置为:", move([0, 1], 120))
>>>
开始移动,移动后的位置为: (0, 70)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-29 16:06:18 | 显示全部楼层
origin = (0, 0)
legal_x = (-100, 100)
legal_y = (-100, 100)

def create(pos_x=0, pos_y=0):
    def moving(direction, step):
        nonlocal pos_x, pos_y
        new_x = pos_x + direction[0] * step
        new_y = pos_y + direction[1] * step

        if new_x < legal_x[0]:
            pos_x = legal_x[0] - (new_x - legal_x[0])
        elif new_x > legal_x[1]:
            pos_x = legal_x[1] - (new_x - legal_x[1])
        else:
            pos_x = new_x

        if new_y < legal_y[0]:
            pos_y = legal_y[0] - (new_y - legal_y[0])
        elif new_y > legal_y[1]:
            pos_y = legal_y[1] - (new_y - legal_y[1])
        else:
            pos_y = new_y

        return pos_x, pos_y
    return moving

def isDirec(char):
    if char == "上":
        direc = [0, 1]
    elif char == "下":
        direc = [0, -1]
    elif char == "左":
        direc = [-1, 0]
    elif char == "右":
        direc = [1, 0]
    elif char == "左上":
        direc = [-1, 1]
    elif char == "左下":
        direc = [-1, -1]
    elif char == "右上":
        direc = [1, 1]
    elif char == "右下":
        direc = [1, -1]
    return direc


sologan = True

b = input("开始游戏(y/n):")
while b != 'y' and b != 'n':
    b = input("开始游戏(y/n):")
if b == 'n':
    sologan = False

a = create()
while sologan:
    char = input("请输入方向('0'退出):")
    while char  == "" or char not in ["上", "下", "左", "右", "左上", "左下", "右上", "右下", '0']:
        char = input("请输入方向('0'退出):")
    if char == '0':
        break

    direc = isDirec(char)

    stepp = input("请输入步数(数字):")
    while not stepp.isdigit():
        stepp = input("请输入步数(数字):")
    stepp = int(stepp)

    print(f"向{char}移动{stepp}后,位置是{a(direc, stepp)}")
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

 楼主| 发表于 2022-6-2 17:13:56 | 显示全部楼层

会,对象在失去引用后由垃圾回收机制负责释放。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-6 23:05:39 | 显示全部楼层
感觉闭包比较关键的一步就是要return 内部函数名
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-9-23 15:45:58 | 显示全部楼层
闭包怎么才能重新清零
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-6 17:22:35 | 显示全部楼层
闭包真的很妙啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-12 16:12:57 | 显示全部楼层
滴滴滴~打卡
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-21 09:40:46 | 显示全部楼层
不太好理解啊,个人感觉是内部函数调用外部函数变量,而这个变量不会与全局变量互相影响,因此是相当于闭包起来了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-25 16:48:24 | 显示全部楼层
def funX(x):
    def funy(y):
        return x*y
    return funy
temp = funX(8)
temp(5)

求大神解答,如何得出是40,有逻辑图么?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-7 10:50:37 | 显示全部楼层
vis黄昏 发表于 2022-10-25 16:48
def funX(x):
    def funy(y):
        return x*y

temp = funX(8) = funy   #此时将参数 x=8 传入函数funy中,得函数 funy() = 8y
temp(5) = funy(5) #此时将参参数 y= 5传入函数funy中,得 return 8*5,既40
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-7 15:48:02 | 显示全部楼层
Learning...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-22 18:54:42 | 显示全部楼层
想知道原理,为什么会这样,只记住了形式,对于其内容还是不理解,总是忍不住去想
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-12-4 11:40:57 | 显示全部楼层
问答题答案:



动动手答案:


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

使用道具 举报

发表于 2022-12-18 12:12:17 | 显示全部楼层
知道怎么调用,还是想不通原理


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

使用道具 举报

发表于 2022-12-30 17:21:38 | 显示全部楼层
嘀嘀嘀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-1-2 13:23:09 | 显示全部楼层
打卡
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-22 13:20

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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