Loading

python函数式编程

根据廖雪峰老师的python教程进行了学习
@

高阶函数

map

输入一个iterable(list,tuple等)和一个函数

对这个iterable的每一个元素都执行相应的函数

返回结果放置到新的iterator

def f(x):
    return x * x
r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
list(r)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
list(map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9]))
['1', '2', '3', '4', '5', '6', '7', '8', '9']

reduce

第一个元素和第二个元素运算,结果再和第三个元素进行运算,以此类推

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
from functools import reduce
def add(x, y):
    return x + y
reduce(add, [1, 3, 5, 7, 9])
25
def fn(x, y):
    return x * 10 + y
reduce(fn,[1,2,3,4])
1234

filter

接收一个函数和一个序列

filter()把传入的函数依次作用于每个元素

根据返回值是True还是False决定保留还是丢弃该元素。

#一个判断是否为奇数的函数
def is_odd(n):
    return n % 2 == 1

list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
[1, 5, 9, 15]
def not_empty(s):
    return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', '  ']))
['A', 'B', 'C']

sorted

接受一个序列和一个函数

函数不是布尔类型的 它是用于对序列的每一个元素进行处理

sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
sorted(['bob', 'about', 'Zoo', 'Credit'])#默认针对ascii码进行排序
['Credit', 'Zoo', 'about', 'bob']
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']

lambda表达式

# 正常函数的写法
def f1(x):
    return x * x
#lambda表达式的写法
f2 = lambda x:x*x
print(f1(10))
print(f2(20))
100
400

装饰器

类似于java中spring的aop功能

函数对象的__name__属性

def fun1():
    print("it's fun1")
f = fun1
f()
fun1()#运行效果是一样的
it's fun1
it's fun1
print(f.__name__)
print(fun1.__name__)##函数的__name__属性就是定义函数的时候的名字,而不是赋给的变量名
fun1
fun1

定义装饰器

定义装饰器也就是定义一个函数

这个函数传入的参数是一个函数

在函数体内定义一个新的函数,这个函数会去调用外面的这个装饰器函数的参数(函数)

返回的结果是刚刚定义的新的函数

最普通的装饰器

def log(func):
    def wrapper(*args, **kw):
        print('调用前')
        print('call %s():' % func.__name__)
        result =  func(*args, **kw)
        print('调用后')
        return result
    return wrapper

添加了文本的装饰器

在普通的装饰器外面再加上一层函数来嵌套

传入的参数为文本

返回结果为装饰器

def log3(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('这是log3装饰器')
            return func(*args, **kw)
        return wrapper
    return decorator

使用装饰器

在需要加上装饰器的函数上面添加@+装饰器名称

@log
def fun2():
    print("it's fun2")
fun2()
调用前
call fun2():
it's fun2
调用后
@log3('fun3 decorator')
def fun3():
    print("it's fun3")
fun3()
这是log3装饰器
it's fun3

奇怪的情况出现了 使用了装饰器之后 fun3函数的名字竟然变了

fun3.__name__
'wrapper'

不改变__name__属性的 装饰器定义的办法

不带参数的装饰器

import functools

#定义装饰器
def log4(func):
    @functools.wraps(func)##在这里去配置函数的__name__属性
    def wrapper(*args, **kw):
        print('调用前')
        print('call %s():' % func.__name__)
        result =  func(*args, **kw)
        print('调用后')
        return result
    return wrapper

@log4
def fun4():
    print("it's fun4")
print(fun4.__name__)#终于不是wrap了
fun4

带参数的装饰器

#定义装饰器
def log5(text):
    def decorator(func):        
        @functools.wraps(func)##在这里去配置函数的__name__属性
        def wrapper(*args, **kw):
            print('调用前')
            print('call %s():' % func.__name__)
            result =  func(*args, **kw)
            print('调用后')
            return result
        return wrapper
    return decorator

@log5('this is just text of log5')
def fun5():
    print("it's fun5")
fun5.__name__
'fun5'

偏函数

就是固定一个变量之后,生成的新的函数

就是去利用functools.partial函数这个去实现,它接受三个参数,分别是原来的函数,位置参数,以及关键字参数

这东西我感觉没什么用,自己完全可以写一个函数去实现这个效果

详见:偏函数

posted @ 2021-03-26 12:19  克豪  阅读(83)  评论(0)    收藏  举报