前言
函数,学过编程语言基础的人都会使用,但是它背后的原理,以及其他扩展特性,不知道你们是否知道呢?
让我们进入今天文章的内容,Python函数的那些事~
函数即变量
什么叫函数即变量呢?有两个理由支撑这个概念:
① 函数可以像变量一样当作参数传递
② 函数的内存分布跟变量是一样的
接下来,我们一一讨论。
函数的内存分布
我们知道,变量的赋值本质上做的就是两件事情:
① 在内存中生成一个新的地址空间,然后压栈;
② 为这片地址空间命名,将变量对应的内存地址绑定到变量名上;
例如:我们声明一个变量—— var = “Hello”,它的内存空间的分布是这样的…
要记住一点是:变量名是内存地址的引用。
而函数也是大同小异,当我们使用一下代码块声明函数时:
1 | def func(a,b): |
它的底层操作是这样的:
① 看到def关键字,会在内存空间中创建一个新空间,存储着函数体
② 将func函数名指向了这片新空间的引用
函数可以当作参数传递
- 我们将函数体赋值给另一个变量var,发现var()也可以运行成功。
- 我们了解了上面的内存分布后,就很容易理解这个行为了:函数体的内存空间多了一个新变量的引用。
- 我们将len函数当成一个参数传给了sort()方法中的key关键字,让sort依据列表中参数的字符长度进行排序
- 关于key关键字,任何单参数函数都能作为 key 参数的运行依据(自定义的函数也可以)
所以,我们发现,函数有着跟变量非常相似的行为与功能,这就是函数即变量的推理了。
函数的可调用性
函数的可调用性是如何实现的呢?
- 可以看到,我们只是运行了c1这个类的实例,它就自动调用了speak方法;
- 原因是我们重构了
__call__
这个特殊方法,这也说明小括弧就是在调用__call__
的过程
判断是否可调用
Python中,可调用对象有很多,判断对象是否能调用,最安全的方法是使用内置的callable()函数:
有了这一章做铺垫以后,无论是魔法函数还是装饰器等等,我们都可以轻易的套用知识去理解它。
下一次更新预知:函数装饰器和闭包
期待跟你一起傲游 python语言,拜拜~