python-高阶函数与闭包

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>,)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值