鱼C论坛

 找回密码
 立即注册
查看: 2810|回复: 5

[已解决]关于返回函数,新手纠结到凌晨2点的疑问,跪求权威解惑!!!

[复制链接]
发表于 2017-1-9 02:20:12 | 显示全部楼层 |阅读模式

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

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

x



  1. def count():
  2.     fs = []
  3.     for i in range(1, 4):
  4.         def f():
  5.              return i*i
  6.         fs.append(f)
  7.     return fs

  8. f1, f2, f3 = count()
复制代码

疑问一:fs是个列表,那么count()的返回值就是个列表,type(count())类型为列表,这个函数还是个闭包吗?

疑问二:f1, f2, f3 = count()  是否等价于a1, a2, a3 =[f(1),f(2),f(3)],原理是什么(type(f1)为函数,type(count())为list)?

疑问三:针对f1(),f2(),f3()函数最后运行结果均为9,跪求代码详细运行步骤分析,一定要详细
最佳答案
2017-1-9 15:57:59
LOAD_CLOSURE
MAKE_CLOSURE
这2个字节码是构造闭包的指令,所以,fs 里保存的是闭包对象。
因为,闭包里只保存了i的引用,所以在闭包执行时,得到i最后的值(3)
>>> import dis
>>> def count():
    fs = []
    for i in range(1, 4):
        def f():
             return id(i),i*i
        fs.append(f)
    return fs

>>> dis.dis(count)
  2           0 BUILD_LIST               0
              3 STORE_FAST               0 (fs)

  3           6 SETUP_LOOP              54 (to 63)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_CONST               1 (1)
             15 LOAD_CONST               2 (4)
             18 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
             21 GET_ITER
        >>   22 FOR_ITER                37 (to 62)
             25 STORE_DEREF              0 (i)

  4          28 LOAD_CLOSURE             0 (i)
             31 BUILD_TUPLE              1
             34 LOAD_CONST               3 (<code object f at 0x019FC5C0, file "<pyshell#87>", line 4>)
             37 LOAD_CONST               4 ('count.<locals>.f')
             40 MAKE_CLOSURE             0
             43 STORE_FAST               1 (f)

  6          46 LOAD_FAST                0 (fs)
             49 LOAD_ATTR                1 (append)
             52 LOAD_FAST                1 (f)
             55 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             58 POP_TOP
             59 JUMP_ABSOLUTE           22
        >>   62 POP_BLOCK

  7     >>   63 LOAD_FAST                0 (fs)
             66 RETURN_VALUE
>>> l=count()
>>> l[0](),l[1](),l[2]()
((505996176, 9), (505996176, 9), (505996176, 9))
>>>
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-1-9 09:13:16 | 显示全部楼层
你的这个函数有问题,
def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f())
    return fs

f1, f2, f3 = count()

函数调用后面需要加括号,这样才是返回结果。不然只是返回的函数的方法。

  1. def count():
  2.     fs = []
  3.     for i in range(1, 4):
  4.         def f():
  5.              return i*i
  6.         fs.append(f())
  7.     return fs

  8. f1, f2, f3 = count()
  9. print (f1,f2,f3)
复制代码

输出:
1 4 9
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-9 15:57:59 | 显示全部楼层    本楼为最佳答案   
LOAD_CLOSURE
MAKE_CLOSURE
这2个字节码是构造闭包的指令,所以,fs 里保存的是闭包对象。
因为,闭包里只保存了i的引用,所以在闭包执行时,得到i最后的值(3)
>>> import dis
>>> def count():
    fs = []
    for i in range(1, 4):
        def f():
             return id(i),i*i
        fs.append(f)
    return fs

>>> dis.dis(count)
  2           0 BUILD_LIST               0
              3 STORE_FAST               0 (fs)

  3           6 SETUP_LOOP              54 (to 63)
              9 LOAD_GLOBAL              0 (range)
             12 LOAD_CONST               1 (1)
             15 LOAD_CONST               2 (4)
             18 CALL_FUNCTION            2 (2 positional, 0 keyword pair)
             21 GET_ITER
        >>   22 FOR_ITER                37 (to 62)
             25 STORE_DEREF              0 (i)

  4          28 LOAD_CLOSURE             0 (i)
             31 BUILD_TUPLE              1
             34 LOAD_CONST               3 (<code object f at 0x019FC5C0, file "<pyshell#87>", line 4>)
             37 LOAD_CONST               4 ('count.<locals>.f')
             40 MAKE_CLOSURE             0
             43 STORE_FAST               1 (f)

  6          46 LOAD_FAST                0 (fs)
             49 LOAD_ATTR                1 (append)
             52 LOAD_FAST                1 (f)
             55 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             58 POP_TOP
             59 JUMP_ABSOLUTE           22
        >>   62 POP_BLOCK

  7     >>   63 LOAD_FAST                0 (fs)
             66 RETURN_VALUE
>>> l=count()
>>> l[0](),l[1](),l[2]()
((505996176, 9), (505996176, 9), (505996176, 9))
>>>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2017-1-9 16:09:40 | 显示全部楼层
正确的写法
>>> def cnt(i):
        def clsr():
                return id(i),i
        return clsr

>>> ls_clsr=[cnt(i)for i in range(1,4)]
>>> ls_clsr
[<function cnt.<locals>.clsr at 0x019FF3D8>, <function cnt.<locals>.clsr at 0x019FF420>, <function cnt.<locals>.clsr at 0x019FF468>]
>>> ls_clsr[0](),ls_clsr[1](),ls_clsr[2]()
((505996144, 1), (505996160, 2), (505996176, 3))
>>> dis.dis(cnt)
  2           0 LOAD_CLOSURE             0 (i)
              3 BUILD_TUPLE              1
              6 LOAD_CONST               1 (<code object clsr at 0x019FC7A0, file "<pyshell#96>", line 2>)
              9 LOAD_CONST               2 ('cnt.<locals>.clsr')
             12 MAKE_CLOSURE             0
             15 STORE_FAST               1 (clsr)

  4          18 LOAD_FAST                1 (clsr)
             21 RETURN_VALUE
>>>
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2017-1-9 21:45:33 | 显示全部楼层
SixPy 发表于 2017-1-9 15:57
LOAD_CLOSURE
MAKE_CLOSURE
这2个字节码是构造闭包的指令,所以,fs 里保存的是闭包对象。

谢谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-10 12:23:41 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-9-28 03:41

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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