1、函数名
-
在python中,一切皆对象(都是
object
的派生类),如下In [1]: string = 'abcd' In [2]: print(type(string)) # 字符串是一个字符串对象 <class 'str'> In [3]: print(str.split) # str.split是属于字符串类的一个方法 <method 'split' of 'str' objects> In [4]: def func(): ...: pass ...: ...: In [5]: print(func) # 一个函数也是一个函数对象 <function func at 0x1074c4e18> In [24]: print(type.__doc__) # type是一个函数,也是对象,__doc__就是type的一个属性 type(object_or_name, bases, dict) type(object) -> the object's type type(name, bases, dict) -> a new type
- 例如所有字符串都是属于字符串类的(具体)对象
-
函数名的应用
-
函数名就是一个变量
-
函数名可以做函数的参数或返回值,也就是所谓的高阶函数
-
高阶函数的例子
In [13]: def calculate(num_list, func): ...: return func(num_list) ...: ...: In [14]: def f_add(lis): ...: s = 0 ...: for item in lis: ...: s += item ...: return s ...: ...: In [15]: def f_product(lis): ...: s = 1 ...: for item in lis: ...: s *= item ...: return s ...: ...: In [16]: l = [1, 2, 3, 4, 5, 6] In [17]: calculate(l, f_add) # 将一个函数名作为实参传入另一个函数中 Out[17]: 21 In [18]: calculate(l, f_product) Out[18]: 720
- 这个例子只是简单的说明函数也是一个变量,可以作为另一个函数的输入参数,也可以作为另一个函数的返回值,高阶函数还有其它很多有用的特性,感兴趣可以自行查阅相关资料
-
2、闭包
-
闭包:在内层函数中访问外层函数的变量,闭包的作用如下
-
闭包可以保护变量不受侵害
In [6]: def outer(): ...: num = 10 # num对外界是不开放的,在outer函数外部无法改变num ...: def inner(): ...: print(num) ...: inner() ...: In [7]: outer() 10
- 当我们想在一个函数中访问另一个函数里的某个变量,又不想让该变量暴露到全局作用域里时,就可以使用闭包的特性
-
闭包可以让一个变量常驻内存(再次读取该变量时速度会很快)
In [28]: def outer(): ...: a = [1, 2, 3] ...: def inner(): ...: return a ...: return inner ...: ...: In [31]: fn = outer() # 当调用outer时,返回inner,则fn=inner,由于fn的调用时间不定,则a必须一直存在于内存中 In [32]: fn Out[32]: <function __main__.outer.<locals>.inner()>
- 当调用outer()时,该函数被执行,创建了a和inner函数(未执行outer函数前,只是定义了函数语句,并没有真正创建变量,也就是只在内存中划了一块地址用来存放这些语句,等到执行函数时,再把这些语句调用出来并执行,这时候才创建了函数里定义的变量以及函数inner才被创建)
- 在不需要使用a变量前,由于fn函数(即inner函数)未被调用,变量a会一直存在于内存中,直到我们调用fn函数,返回a的值后,这时候fn函数和a变量才被清除
- 这里a是一个简单的列表,假如a是一个很大的数据,又经常使用,便可以这样定义a
- 话虽如此,但是总感觉自己对闭包的这个作用的理解还有哪里不到位,如果有更好的见解,欢迎在评论区指出,或者私信我,万分感谢
-
-
查看一个函数是不是闭包:
print(fuction.__closure__)
,如果为None则不是闭包In [27]: def outer(): ...: a = [1, 2, 3] ...: def inner(): ...: return a ...: In [28]: def outer(): ...: a = [1, 2, 3] ...: def inner(): ...: return a ...: return inner ...: ...: In [35]: print(outer().__closure__) (<cell at 0x10757d678: list object at 0x1073c95c8>,)