Python学习笔记——函数式编程

函数式

函数式:functional 一种编程范式
函数式编程是一种抽象计算的编程模式

特点:
把计算视为函数而非指令
纯函数式编程:不需要变量,没有副作用,测试简单
支持高阶函数,代码简洁

python
不是纯函数式编程:允许有变量
支持高阶函数:函数可以作为变量传入
支持闭包:有来闭包就能返回函数
有限的支持匿名函数

闭包(Closure)是词法闭包(Lexical Closure)的简称,
内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数
如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。它只不过是个“内层”的函数,由一个名字(变量)来指代,而这个名字(变量)对于“外层”包含它的函数而言,是本地变量。

返回函数不要引用任何循环变量,或者后续会发生变化的变量。
1. 希望一次返回3个函数,分别计算1x1,2x2,3x3:

def count():
    fs = []
    for i in range(1, 4):
        def f(j):
            def g():
                return j*j
            return g
        r = f(i)
        fs.append(r)
    return fs
f1, f2, f3 = count()
print f1(), f2(), f3()

或者

def count():
        fs = []
        for i in range(1,4):
                def f(j=i):
                        return j*j
                fs.append(f)
        return fs

f1,f2,f3 = count()
print f1(),f2(),f3()

作用:1.当闭包执行完后,仍然能够保持住当前的运行环境。
2.闭包可以根据外部作用域的局部变量来得到不同的结果,类似配置功能的作用,我们可以修改外部的变量,闭包根据这个变量展现出不同的功能。

高阶函数

变量可以指向函数
函数名其实就是窒息那该函数的变量

高阶函数:能接收函数作为参数
(Python为string对象提供了转换大小写的方法:upper() 和 lower().
还不止这些,Python还为我们提供了首字母大写,其余小写的capitalize()方法,
以及所有单词首字母大写,其余小写的title()方法.)

  1. map(f,list)
    它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。(对元祖进行来“解包”操作)

  2. reduce(f,list)
    python3使用要导入functools
    函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。
    求和:

def f(x,y):
    return x+y
reduce(f,[1,2,5,7,9])

3.filter(f,list)
收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
删除 None 或者空字符串:

def is_not_empty(s):
    return s and len(s.strip()) > 0
filter(is_not_empty, ['test', None, '', 'str', '  ', 'END'])
#或匿名函数
print filter(lambda s: s and len(s.strip())>0, ['test', None, '', 'str', '  ', 'END'])

4.sorted(list,f)
传入两个待比较的元素 x, y,如果 x 应该排在 y 的前面,返回 -1,如果 x 应该排在 y 的后面,返回 1。如果 x 和 y 相等,返回 0。
忽略大小写:

def cmp_ignore_case(s1, s2):
        return cmp(s1.lower(), s2.lower())
    print sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)

匿名函数

不显示地定义函数,直接传入匿名函数更为方便

关键字lambda

匿名函数有个限制,就是只能有一个表达式,不写return,返回值就是该表达式的结果

装饰器 decorator

在函数运行时动态的增加功能,但不改动函数本身代码。可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能

通过高阶函数返回新函数

def f1(x):
    return x*2
def new_fn(f):  #装饰器
    def fn(x):
        print 'call' + f.__name__ + '()'
        return f(x)
    return fn
#调用装饰器
#1. 间接
# g1 = new_fn(f1)
# print g1(5)
#2. 彻底隐藏f1的原始定义函数
f1 = new_fn(f1)
print f1(f1)

python内置@语法简化装饰器调用

@new_fn
 def f1(x):
     return x*2

相当于

def f1(x):
    return x*2
f1 = new_fn(f1)

简化代码,避免每个函数编写重复性代码
打印日志 @log
检测性能 @performance
数据库事物 @transaction
URL路由 @post(‘/register’)

*args 代表任意个普通参数,**kw代表任意个用=号指定默认值的参数
*args 是元组 、**kw是字典

无参数的 decorator

打印出函数调用的时间:

import time
def performance(f):
        def fn(*args, **kw):
            t1 = time.time()
            r = f(*args, **kw)
            t2 = time.time()
            print 'call %s() in %fs' % (f.__name__, (t2 - t1))
            return r
        return fn

@performance
def factorial(n):
    return reduce(lambda x,y: x*y, range(1, n+1))
print factorial(10)
有参数的 decorator

允许传入’s’或’ms’:

import time,functools
def performance(unit):
    def perf_decorator(f):
        @functools.wraps(f)
        def wrapper(*args,**kw):
            t1 = time.time()
            r = f(*args,**kw)
            t2 = time.time()
            t = (t2 - t1)*1000 if unit == 'ms' else (t2 - t1)
            print 'call %s() in %f %s' % (f.__name__,t,unit)
            return r
        return wrapper
    return perf_decorator

@performance('ms')
def factorial(n):
    return reduce(lambda x,y:x*y,range(1,n+1))
print factorial(10)

Python内置的functools来复制原函数的属性

偏函数

functools.partial可创建偏函数,可以把一个参数多的函数变成一个参数少的新函数,少的参数需要在创建时指定默认值,这样,新函数调用的难度就降低了。

import functools
sorted_ignore_case = functional.partial(sorted,cmp=lambda s1,s2: cmp(s1.lower(),s2.lower()))
print sorted_ignore_case(['bob','about','Zoo','Credit'])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值