鱼C论坛

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

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

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

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

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

  9.         if new_x < legal_x[0]:
  10.             pos_x = legal_x[0] - (new_x - legal_x[0]) # 小于x轴范围时
  11.         elif new_x > legal_x[1]:
  12.             pos_x = legal_x[1] - (new_x - legal_x[1]) # 大于x轴范围时
  13.         else:
  14.             pos_x = new_x

  15.         if new_y < legal_y[0]:
  16.             pos_y = legal_y[0] - (new_y - legal_y[0]) # 小于y轴范围时
  17.         elif new_y > legal_y[1]:
  18.             pos_y = legal_y[1] - (new_y - legal_y[1]) # 大于y轴范围时
  19.         else:
  20.             pos_y = new_y

  21.         return pos_x, pos_y

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

使用道具 举报

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

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

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

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

使用道具 举报

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

  4. def create(pos_x=0, pos_y=0):
  5.     def moving(direction, step):
  6.         nonlocal pos_x, pos_y
  7.         new_x = pos_x + direction[0] * step
  8.         new_y = pos_y + direction[1] * step

  9.         if new_x < legal_x[0]:
  10.             pos_x = legal_x[0] - (new_x - legal_x[0])
  11.         elif new_x > legal_x[1]:
  12.             pos_x = legal_x[1] - (new_x - legal_x[1])
  13.         else:
  14.             pos_x = new_x

  15.         if new_y < legal_y[0]:
  16.             pos_y = legal_y[0] - (new_y - legal_y[0])
  17.         elif new_y > legal_y[1]:
  18.             pos_y = legal_y[1] - (new_y - legal_y[1])
  19.         else:
  20.             pos_y = new_y

  21.         return pos_x, pos_y
  22.     return moving

  23. def isDirec(char):
  24.     if char == "上":
  25.         direc = [0, 1]
  26.     elif char == "下":
  27.         direc = [0, -1]
  28.     elif char == "左":
  29.         direc = [-1, 0]
  30.     elif char == "右":
  31.         direc = [1, 0]
  32.     elif char == "左上":
  33.         direc = [-1, 1]
  34.     elif char == "左下":
  35.         direc = [-1, -1]
  36.     elif char == "右上":
  37.         direc = [1, 1]
  38.     elif char == "右下":
  39.         direc = [1, -1]
  40.     return direc


  41. sologan = True

  42. b = input("开始游戏(y/n):")
  43. while b != 'y' and b != 'n':
  44.     b = input("开始游戏(y/n):")
  45. if b == 'n':
  46.     sologan = False

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

  54.     direc = isDirec(char)

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

  59.     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-4-19 02:08

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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