3.2. 函数式编程

函数式编程是抽象很高的编程范式,允许函数作为参数,允许函数作为返回值。

3.2.1. 函数调用和函数

abs(-10) 表示函数调用, 但是abs是函数本身, 函数本身可以赋值给变量,

3.2.2. 传入函数

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def add(a,b):
    return a+b 
def f2(a,b,f):
    return f(a,b)


f2(2,5,add)

3.2.3. mapreduce

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def f(x):
    return x * x 

r = map(f,[1,2,3])
print(list(r))

from functools import reduce

def add (a,b):
    return a+b 

print(reduce(add,range(1,101)))

# str to int 

from functools import reduce

DIGITS = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

def str2int(s):
    def fn(x,y):
        return x*10 +y 
    def char2num(ch):
        return DIGITS[ch]
    return reduce(fn,map(char2num,s))

3.2.4. filter

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


def is_odd(a):
    if a%2==0:
        return True
    return False 

list(filter(is_odd,range(1,10)))

3.2.5. sorted

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


sorted([5,1,2,4])

sorted([5,1,2,4],key=abs)

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



3.2.6. 函数作为返回值

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def calc_sum(*args):
    s=0
    for i in args:
        s+=i
    return s 

def lazy_sum(*args):
    def calc_sum():
        s=0
        for i in args:
            s+=i
        return s 
    return calc_sum

f = lazy_sum
print(f)
print(f(1,2,4))
print(f(1,2,4)())

3.2.7. 闭包

内部函数使用外部函数的变量。

使用闭包时,对外层变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量。

def inc():
 x = 0
 def fn():
     # nonlocal x
     x = x + 1
     return x
 return fn

f = inc()
print(f()) # 1
print(f()) # 2

3.2.8. 匿名函数

def f(x):
   return x * x

f2 = lamba x: x*x

3.2.9. 装饰器

增强函数功能,但是不修改原有函数代码。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def now():
    print('2024.01.01')

def log(func):
    def wrapper(*args,**kw):
        func_name = func.__name__
        print(f"call {func_name} start")
        return func(*args,**kw)
    return wrapper

now()

@log
def now2():
    print('2024.01.01')

now2()

def now3():
    print('2024.01.01')
now3= log(now3)

now3()


# 设计一个计时器装饰圈
import time ,functools

def metric(func):
    @functools.wraps(func)
    def wrapper(*args,**kw):
        start =  time.time()
        res = func(*args,**kw)
        end = time.time()
        print("exec <{}> time: {}".format(func.__name__,end-start))
        return res 
    return wrapper

@metric
def fast(x, y):
    time.sleep(0.0012)
    return x + y


fast(1,2)

3.2.10. 偏函数

固定一些参数,方便函数调用。

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

print(int("12345",base=8))

def int8(x):
    return int(x,base=8)

print(int8("12345"))

from  functools import partial
int88 = partial(int,base=8)
print(int88("12345"))