【python基础】 函数式编程

本章包含:高阶函数、闭包、匿名函数、装饰器、偏函数
参考:廖雪峰python

函数式编程

  • 高阶函数
    • 高阶函数定义
    • map函数
    • reduce函数
    • filter函数
    • sorted函数
  • 匿名函数
    • 作为参数使用
    • 匿名函数对象
    • 作为函数返回值
  • 闭包
    • 返回函数
    • 闭包特点
    • 外部函数变量赋值
  • 装饰器
    • 多个装饰器
    • 传入参数
  • 偏函数

高阶函数

高阶函数定义

一个函数接受另一个函数为参数,则称这个函数为高阶函数
【python基础】 函数式编程_第1张图片

map函数

map函数接受两个参数,一个是函数,一个是iterable。
map将传入的函数依次作用到每个iterable元素,然后返回iterator。可使用list转换为列表。

【python基础】 函数式编程_第2张图片

reduce函数

导入库:from functools import reduce

reduce函数接受两个参数,一个是函数,一个是iterable。
这个参数函数必须能接受两个参数,函数作用在每个元素上,每一次的结果和下一个元素做累积计算。

比如生成如下:

【python基础】 函数式编程_第3张图片

filter函数

filter函数接受两个参数,一个函数,一个iterable。
传入的函数作用到每个元素,返回True或False来决定是否丢弃该元素。返回Iterator
【python基础】 函数式编程_第4张图片

生成素数例子:

def odd_iter():  # 奇数生成器
    n = 1
    while True:
        n = n+2
        yield n

def not_divisible(n): #如果是2 3 5...倍数,筛选掉
    return lambda x: x % n >0 

def primes():
    yield 2
    it = odd_iter() # 初始序列
    while True:
        n = next(it) # 返回序列的第一个数
        yield n
        it = filter(not_divisible(n), it) # 构造新序列
        
for n in primes():
    if n < 1000:
        print(n)
    else:
        break

sorted函数

sorted函数传入iterable,其中key和reverse可选参数
【python基础】 函数式编程_第5张图片

匿名函数

作为参数使用

l = list(map(lambda x:x*x,[1,2,3,4]))
print(l)

#[1,4,9,16]

匿名函数对象

f = lambda x: x+1
f(2)

# 3

作为函数返回值

调用时,返回的是lambda函数,因此还要再一次调用
【python基础】 函数式编程_第6张图片

闭包

返回函数

把函数作为返回值的函数叫做返回函数。

下面例子中,lazy_sum的返回值是sum函数,故vsum函数的引用。再一次使用v()便可得到求和。

def lazy_sum(*args):
    def sum():
        n = 0
        for i in args:
            n += i
        return n
    return sum

v = lazy_sum(1,3,5,6,7) #此时v就是sum的引用
v()      #调用sum()

闭包特点

外层函数作用域变量会以某种形式保留下来。

下面例子,先定义两个power,exp值分别为2和3。定义完了之后,其变量就以闭包的形式保留了下来(原本函数结束,作用域也会消失)。

def power(exp):
    def exp_of(base):
        return base**exp
    return exp_of

square = power(2) 
cube = power(3)
print(square(2)) #exp_of(2) —— exp =2 被保留
print(square(5))
print(cube(3))

#4
#25
#27

外部函数变量赋值

如果内部函数需要对外部函数变量赋值,则使用nonlocal声明。

def func1():
    x = 0
    y = 0
    def func2(x1,y1):
        nonlocal x,y
        x += x1
        y += y1
        print(f'x is {x}, y is {y}')
    return func2

f = func1()
f(1,2)
f(3,4)
       
#x is 1, y is 2
#x is 4, y is 6      

装饰器

装饰器就是函数想要增加一些功能,但又不想修改原函数时,会使用的东西。

def dec(func):
    def mes():
        print('正在调用 {0}'.format(func.__name__))
        func()
    return mes

@dec
def func2():   
    print('这是func2')

func2()

#正在调用 func2
#这是func2

上面代码等价于:(可见装饰器是闭包的高阶函数)

def dec(func):
    def mes():
        print('正在调用 {0}'.format(func.__name__))
        func()
    return mes

def func2():
    print('这是func2')

    
func2 = dec(func2) # mes()函数
func2()

多个装饰器

def add(func):
    def inner():
        x = func()
        return x+1
    return inner

def cube(func):
    def inner():
        x = func()
        return x*x*x
    return inner

def square(func):
    def inner():
        x = func()
        return x*x
    return inner

@add    
@cube
@square
def func():
    return 2

print(func())

# 65 
#先调用square、cube、add

传入参数

def func1(mes):
    def func2(func):
        def func3():
            print('正在调用 {0}'.format(func.__name__))
            func()
            print('传入的message是 {0}'.format(mes))
        return func3
    return func2

@func1('Jeff')
def func():
    print('this is func')

    
@func1('Handsome')
def funcb():
    print('this is funcb')
    
func()
funcb()


#正在调用 func
#this is func
#传入的message是 Jeff
#正在调用 funcb
#this is funcb
#传入的message是 Handsome

偏函数

通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。

导入库import functools,使用 functools.partial(函数,参数=X)

import functools

a = int('111',base=2)
print(a)

int2 = functools.partial(int,base=2)
b = int2('111')
print(b)

#7
#7

你可能感兴趣的:(python基础,python,开发语言,大数据)