python—函数式编程

栏目: Python · 发布时间: 6年前

内容简介:python—函数式编程
  • 纯函数式编程没有变量,一个函数只要输出确定,输出就是确定的,称为没有副作用.使用变量的函数内部由于变量状态不确定性,有副作用.
  • 函数式编程另一个特点是允许函数本身作为参数传入,也可以直接返回另外一个函数.
  • python对函数式编程提供有限支持.(还使用变量 so不是纯函数式编程语言)

    高阶函数

  • python中函数本身也可以赋值给变量,变量可以指向函数
  • 函数的参数可以传入另一个函数,这种函数称为高阶函数.

map/reduce

  • map()接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回
  • 示例

    list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]) # list所有数字转为字符串
    
  • reduce把一个函数作用在一个序列[x1, x2, x3, …]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算

  • 示例
    >>>from functools import reduce
    >>>def fn(x, y):
    ...    return x * 10 + y
    ...
    >>>def char2num(s):
    ...    digits = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
    ...    return digits[s]
    ...
    >>>reduce(fn, map(char2num, '13579'))
    13579
    

filter

  • filter()接收一个函数和一个序列。filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
  • filter()函数返回的是一个 惰性序列 Iterator,也就是一个惰性序列,需要用list()函数获得所有结果并返回list
  • 示例
    def is_odd(n):
      return n % 2 == 1
    
    list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])) # 只保留奇数
    
    def not_empty(s):
      return s and s.strip()
    
    list(filter(not_empty, ['A', '', 'B', None, 'C', ' '])) # 删除空字符
    

sorted

  • sorted()函数接收一个key函数来实现自定义的排序.第三个参数 reverse=True 决定正序倒序.
  • 示例:

      >>> sorted(['bob', 'about', 'Zoo', 'Credit'],key=str.lower)
      ['about', 'bob', 'Credit', 'Zoo']
    
      >>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
      ['Zoo', 'Credit', 'bob', 'about']
      ``` 
    
    ### 返回函数
    * 将函数作为结果返回.(很随便:joy:)
    * 闭包(Closure):相关参数和变量都保存在返回函数.
    * **note:**返回的函数在其定义内部引用了局部变量args,所以,当一个函数返回了一个函数后,其内部的局部变量还被新函数引用
    * 示例(坑):
      ```py
      def count():
        fs = []
        for i in range(1, 4):
            def f():
                 return i*i
            fs.append(f)
        return fs
    
      f1, f2, f3 = count()
    
      >>> f1()
      9
      >>> f2()
      9
      >>> f3()
      9
    
  • 返回的函数引用了变量i,但它并非立刻执行。等到3个函数都返回时,它们所引用的变量i已经变成了3,因此最终结果为9

  • 一定要引用循环变量怎么办?方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变
  • 示例:
    def count():
      def f(j):
          def g():
              return j*j
          return g
      fs = []
      for i in range(1, 4):
          fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
      return fs
    

匿名函数

  • 不显式定义的函数. python中是 lambda 但与 java 不同.
  • python中 lambda 限制,只能有一个表达式,不用写return,返回值就是该表达式的结果
  • 匿名函数不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
  • 示例
    f = lambda x: x * x
    

装饰器

  • 代码运行期间,动态增加功能方式称为装饰器(Decorator)
  • 示例

    def log(func):
      def wrapper(*args, **kw):
          print('call %s():' % func.__name__)
          return func(*args, **kw)
      return wrapper
    
    @log
    def now():
      print('2015-3-25')
    
    >>>now()
    call now():
    2015-3-25
    
  • 如示例,装饰器 接受一个函数作为参数,并返回原函数.在原函数定义时,以 @ xxx 作为标记.示例1 为2层,如果打印文本可以自定义.

  • 示例

    def log(text):
      def decorator(func):
          def wrapper(*args, **kw):
              print('%s %s():' % (text, func.__name__))
              return func(*args, **kw)
          return wrapper
      return decorator
    
    @log('execute')
    def now():
      print('2015-3-25')
    
    >>>now()
    execute now():
    2015-3-25
    

    打印可自定义 又加上了一层.

  • 如上两种定义后,函数对象的名称等发生了变化,so,终极版

  • Python内置的functools.wraps 会将原始函数的 __name__ 等属性复制到wrapper()函数中.
  • 示例
    import functools
    # 不带参数
    def log(func):
    @functools.wraps(func)
        def wrapper(*args, **kw):
            print('call %s():' % func.__name__)
            return func(*args, **kw)
        return wrapper
    
    # 带参数
    
    def log(text):
        def decorator(func):
    @functools.wraps(func)
            def wrapper(*args, **kw):
                print('%s %s():' % (text, func.__name__))
                return func(*args, **kw)
            return wrapper
        return decorator
    

偏函数

  • functools.partial的作用是把一个函数的某些参数设置默认值,返回一个新的函数.
  • 示例:

    import functools
    int2 = functools.partial(int, base=2)
    
    int2('1000000')
    
  • 注意: 仅仅是把base参数重新设定默认值为2, 但也可以在函数调用时传入其他值

  • 由于 python 中函数也可以最为参数传入,so,参数固定成某一个函数也可.
  • 同理: *args**kw 也可以.

  • 简化函数调用.


以上所述就是小编给大家介绍的《python—函数式编程》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

C++编程风格

C++编程风格

卡吉尔 / 聂雪军 / 机械工业出版社发行室 / 2007-1 / 25.00元

本书描述C++语言中较深层次的程序设计思想和使用方法,包含大量软件工程概念和设计模式,重点介绍大规模编程相关的内容,例如增加代码的可读性、可维护性、可扩展性以及执行效率等的方法。本书的示例代码都是从实际程序中抽取出来的,融人了作者的实际开发经验。讲解如何正确地编写代码以及避开一些常见的误区和陷阱,并给出了许多实用的编程规则,可快速提升读者的C++编程功力。   本书描述平实,示例丰富,适合有......一起来看看 《C++编程风格》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具