Python 函数式编程入门

[TOC]
学 python3 也有一段时间了,关于函数式编程也看了很多遍,总是记不住,大概因为平时也忘记用。
整理了网上部分教程。
因为是针对Python写的,直接偷懒参考了廖雪峰老师的分类方法。

主要通过实例来直观地呈现

函数式编程

函数式编程主要用了映射的思维,思维方式区别于面对对象编程(OOP属于一种过程式编程)
从名字上大概可以体会到,编程过程中更多会考虑到映射关系,方便了编写。

高阶函数

函数本身可以赋值给变量,操作有:传入,赋值,返回值等等

map/reduce

与其他语言类似,map 表示映射的关系。
map 的返回值是 map 类型

def f(x):
    return x+1

lst=list(map(f,[1,2,3,4,5]))
#  lst is [2,3,4,5,6]

reduce 用于累积计算。有点像累加器

def f(x,y):
    return x+y

x=reduce(f,[1,2,3,4])
#  x is 10

第一个函数一定要接收两个参数。

filter

英文即为过滤器
和map用法几乎一样,作用于每个元素,但他实现的是保留或筛选的过滤功能
用法如筛奇数:

def check(n):
    return n%2

x=filter(check,[1,2,3,4])
# x is [1,3]

sorted

很好理解,就像 c++ 的 sort 一样,关键在于实现 cmp 一样的 key 函数
reverse 函数 True 为从大到小,False 为从小到大。
key 函数作用于每个元素。

sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)

返回函数

函数可以作为返回值

def calc_sum(*args):
    ax = 0
    for n in args:
        ax = ax + n
    return ax

f=calc_sum([1,2,3])
f()
# f为函数
# f()才为 6

简单地理解就是增加了一个返回函数的功能。

闭包

谈谈自己的理解:Python中的闭包 闭包的实质
闭包用面向对象的思想中封装的思想去理解,还涉及到全局变量和局部变量的关系
从这两点去理解闭包就不难,但是不好写。

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

f1, f2, f3 = count()
f1(),f2(),f3() # 9,9,9

上面的代码中之所以不是 1 4 9 是因为
返回的函数并没有立刻执行,而是直到调用了f()才执行
当调用f()时,变量i已经被修改为3了

用闭包返回一个计数器函数,每次调用它返回递增整数:

def createCounter():
    x=[0]
    def counter():
        x[0]+=1
        return x[0]
    return counter

counterA = createCounter()
print(counterA(), counterA(), counterA(), counterA(), counterA()) # 1 2 3 4 5
counterB = createCounter()
if [counterB(), counterB(), counterB(), counterB()] == [1, 2, 3, 4]:
    print('测试通过!')
else:
    print('测试失败!')

x 不能赋值为0,否则会报错:
local variable 'x' referenced before assignment
意思是 x 在 createCounter 这个函数内是一个局部变量, counter 函数内的 x 又是新开的局部变量,所以显示第二个没有声明。
而 list 是可以这样子对里面元素进行操作的。

匿名函数

就是 lambda 用法,一个实例就可以学会了

L=list(filter(lambda x: x % 2,[1,2,3,4,5]))

装饰器

[译] 12步轻松搞定python装饰器
装饰器属于闭包的应用
看一段代码

>>> def outer(some_func):
...     def inner():
...         print "before some_func"
...         ret = some_func() # 1
...         return ret + 1
...     return inner
>>> def foo():
...     return 1
>>> decorated = outer(foo) # 2
>>> decorated()
before some_func
2

其中 outer 就是一个装饰器,decorated 是 foo 经过 outer 装饰器“加强”后的新函数
和上面讲到的闭包其实没差别,区别在于现在传递的参数是一个函数,而不是普通变量。因此取名“装饰器”,用于装饰函数。
foo=outer(foo) 意思就是本身经过装饰,上面的用法可以用@标识符来应用,等价于:

def outer():
    //todo...

@outer
def foo():
    //todo...

写到这里突然想起来Java里面的的@Override 重写方法,也就很好理解了。

偏函数

偏函数平时看到比较少,在模块functools.partial中。
简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数
,调用这个新函数会更简单。
例子用到了 intmax 的偏函数使用方法。

# 二进制转十进制
int2 = functools.partial(int, base=2)
# 多个数取 max
max2 = functools.partial(max, 10)
max2(5, 6, 7)
# 等价于下面
args = (10, 5, 6, 7)
max(*args)
# answer is 10

猜你喜欢

转载自blog.csdn.net/Joovo/article/details/80684168