欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

Python 里为什么函数可以返回一个函数内部定义的函数?

程序员文章站 2022-03-31 12:26:13
...

回复内容:

题主可能并没有理解

“在Python中,函数本身也是对象”

这一本质。那不妨慢慢来,从最基本的概念开始,讨论一下这个问题:

1. Python中一切皆对象
这恐怕是学习Python最有用的一句话。想必你已经知道Python中的list, tuple, dict等内置数据结构,当你执行:

alist = [1, 2, 3]

题主遇到的这个问题很典型,就是把修饰器当成了包装器, 认为调用 useful 前先调用 addspam。其实 useful 不是被 addspam 包装了,而是替换了。调用 useful 调用的就是 new。余下的 fn 指向原来的 useful, 才需要第一类函数、作用域继承等知识点来理解。可变参数 *args 则是干扰的另外一个知识点,替换成 x, y 就行了。 Python里面的@只是一个syntax sugar而已,在你声明useful的时候,interpreter检查到你有外面有装饰器@addspam的存在,这时候你就可以大致理解成解释器做了以下的手脚:

useful = addspam(useful)

很好的问题!
请搜索higher order functions了解更多信息。
因为我没有能力来清楚地解释,就放几篇我在学习函数式编程的时候看到的比较好的博文来帮助你理解。
函数式编程 | 酷 壳
Python修饰器的函数式编程
1.6 Higher-Order Functions
6. Functional Programming
我喜欢最后一篇文章,通过实例来理解效果更好。 Python中,函数并没有什么特殊的,就是一个对象。 你没理解修饰器。
用addspam修饰了useful后,你应该理解为这个函数变成了new。
当调用useful函数的时候,其实是调用了new。 没有复制,函数也是个对象,基本就和你 return 一个 list 一个 dict 没什么两样。

试试看在 Python REPL 中创建一个 function:

>>> def foobar(): print("你好")
>>> foobar
>>> func_list = [foobar, foobar, foobar]
>>> func_list[0]()

不是简单地返回函数。至少在Python里,def定义的函数和lambda定义的函数,后者是包含closure的。

具体closure是什么,这真不是一句话能说清,我也不觉得我能说好,所以还是自己搜一下吧。

不要说我歧视用百度查这种问题,这去Google搜个nested functions多好。

相关标签: Python