Python-学习之路-12 函数式编程-1

Log模块资料

  • http://www.cnblogs.com/yyds/p/6901864.html

Python语言的高级特性

函数式编程(FunctionalProgramming)

  • 最大程度的复用代码

  • 给予lambda演算的一种编程方式

    • 程序中只有函数
    • 函数可以作为参数,同样可以作为返回值
  • Python函数式编程只是借用函数式编程的一些特点,可以理解成一半函数式一半Python

    • 高阶函数
    • 返回函数
    • 匿名函数
    • 装饰器
    • 偏函数

lambda表达式(匿名函数)

- 一个表达式,函数体相对简单
- 不是一个代码块,仅仅是一个表达式
- 可以有参数(多个参数),多个参数用逗号隔开
#lambda表达式案例
'''
    1、以lambda开头
    2、紧跟一定的参数(如果有的话)
    3、参数后用冒号和表达式主体隔开
    4、只是一个表达式,所以没有return
'''
# 计算一个数的100倍
stm = lambda x:100 *x

print(stm(23))
2300

高阶函数

  • 把函数作为参数使用的函数,叫做高阶函数
# 高阶函数案例
def funA():
    print("this is funA")
    
# 将函数作为参数使用
funB = funA
funB()
this is funA

结论

  • 函数名称是一个变量
  • funB和funA只是名称不一样而已
  • 既然函数名称是变量,则应该可以被当做参数传入另一个函数中

使用场景

  • 对比高阶函数举例2的代码 如果传入数字乘以100这个需求发生变化,那么使用高阶函数的话,funC就不用改变,只需要从新定义一个函数,然后赋值给func即可
# 高阶函数举例 2
# funA是不同函数和,返回一个传入数字的100倍
def funA(n):
    return n * 100

# 在写一个函数,把传入参数乘以300倍
def funB(n):
    return funA(n)*3

print(funB(9))

# 高阶函数
def funC(func,n):
    return func(n) * 3

func = funA
print(funC(func,9))
2700
2700

系统高阶函数 -map

  • 原意就是映射,即班集合或者列表的元素都按照一定的规则进行操作,生成一个新的列表或集合
  • map函数是系统提供的具有映射功能的函数,返回值是一个迭代对象
# map 案例
l1 = [i for i in range(10)]
def multen(n):
    return n * 10

l3 = map(multen,l1)
#map是一个可迭代的类型,所有使用循环将其值取出
for i in l3:
    print(i,end = " ")
0 10 20 30 40 50 60 70 80 90 

reduce

  • 原意是归并,缩减
  • 把一个可迭代对象最后归并成一个结果
  • 对于作为参数的函数要求,必须有两个参数,必须有返回结果
  • reduce(1,2,3,4,5) == f(f(f(f(1,2),3),4),5)
  • reduce 需要导入functools包
# reduce 案例
from functools import reduce

#定义一个操作函数,函数的功能是两个数相加
def add(x,y):
    return x+y
    
#对于列表[1,2,3,4,5,6]只想add方法的reduce操作
rst = reduce(add,[1,2,3,4,5,6])
print(rst)
21

filter 函数

  • 过滤函数:对一组数据进行过滤,符合条件的数据会生成一个新的列表并返回
  • 跟map对比
    • 相同:都对列表的每一个元素逐一进行操作
    • 不同:
      • map会生成一个跟原来列表数据想对象的新队列(个数相同)
      • filter不一定,只有符合条件的才会进入新的数据集合
  • filter函数怎么写:
    • 利用特定函数进行判断
    • 返回值一定是布尔值
    • 调用格式:filter(f,data)
# filter函数列表
#定义一个函数,并返回布尔值

def isEven(a):
    return a % 2 == 0

l = [1,3,34,56,23,42,54,76,345,875,89,348]

rst = filter(isEven,l)

    
print([i for i in rst])
[34, 56, 42, 54, 76, 348]

高阶函数-sorted 排序

  • 把一个序列按照给定的算法进行排序
  • key:排序前对每一个元素进行key函数运算.可以理解成案遭key函数定义的逻辑进行排序
# 排序函数 1
a = [43,67,123,87,213,987,12,56,2,7,89]
al = sorted(a,reverse=True)
print(al)

print()

# 排序函数 2
a = [-45,-34,-1,56,2,67,-9]
# abs 绝对值
al =  sorted(a ,key = abs ,reverse=True)
print(al)

# 排序函数 3
astr = ["asf","my","name","is","Liusi"]
str1 = sorted(astr)
print(str1)

str2 = sorted(astr,key = str.lower)
print(str2)
[987, 213, 123, 89, 87, 67, 56, 43, 12, 7, 2]

[67, 56, -45, -34, -9, 2, -1]
['Liusi', 'asf', 'is', 'my', 'name']
['asf', 'is', 'Liusi', 'my', 'name']

返回函数

  • 函数可以返回具体的值
  • 也可以返回一个函数作为结果
# 返回函数案例

#定义一个普通的函数
def func1(a):
    print("is func1")
    return None

# 定义一个返回函数
def func2(a):
    def func3():
        print("is func3")
        return a
    return func3

# 这里的参数1 作为func2的参数
f3 = func2(1)
# 这里的参数2 最为func3的参数
f3()
is func3





1

闭包 closure

  • 当一个函数在内部定义函数,并且内部的函数应用外部函数的参数或者局部变量,当内部函数被当做返回值的时候,相关参数和变量保存在函数中,这种结果叫做闭包
  • 上述代码就展示的闭包
# 闭包常见的坑
def count():
    #定义一个空列表
    fs = []
    for i in range(1,4):
        #定义一个闭包结构
        def f():
            return i * i
        fs.append(f)
    return fs

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

出现的问题

  • 造成上述状况的原因是,返回函数引用了变量i,i并非立即执行,而是等到三个函数都返回的时候才同意使用,此时i已经变成了3,最终调用的时候,都返回的是3*3
  • 此问题描述成:返回闭包时,返回函数不能引用任何循环变量
  • 解决方案:在创建一个函数,用该函数的参数绑定循环变量的当前值,无论该循环变量以后如何改变,已经绑定的函数参数值不在改变
# 闭包常见的坑
def count2():
    #定义一个空列表
    fs = []
    def f(i):
        def j():
            return i * i
        return j
        
    for i in range(1,4):
        fs.append(f(i))
    return fs

f1,f2,f3 = count2()
print(f1())
print(f2())
print(f3())
1
4
9

装饰器(Dectator)

  • 在不改动函数代码的基础上,无限制扩展函数功能的一种机制,本质上讲,装饰器是一个返回函数的高阶函数
  • 装饰器的使用 使用@语法,及每次扩展到函数定义前使用@+函数名
  • 优点:
    • 一经定义,则可以装饰任意函数
    • 一旦被其装饰,则把装饰功能直接添加到定义函数的功能上
# 装饰器 案例
# 对hello函数进行功能扩展,每次执行hello时,打印当前时间
import time

def printTime(f):
        def wrapper(*args, ** kwargs):
            print("Time:",time.ctime())
            return f(*args,**kwargs)
        return wrapper
    
#使用装饰器
@printTime
def hello():
    print("hello word")
    

hello()
Time: Sun Feb 24 23:36:00 2019
hello word
# 手动执行装饰器
def hello2():
    print("我是手动执行的.....")
    
helloF = printTime(hello2)
helloF()
Time: Sun Feb 24 23:37:18 2019
我是手动执行的.....

偏函数

  • 参数固定的函数,相当于一个有特定参数的函数体
  • functools.partial的作用是,把一个的函数某些参数固定,返回一个新函数
# 把字符串转换成是十进制数字
int("123456")

# 求八进制的字符串123456,表示成十进制的数字是对手
int("123456",base = 8)
42798
# 新建一个和拿书,此函数是默认输入字符串是16进制的数字
# 吧此字符串返回十进制的数字

def int16(x,base = 16):
    return int(x,base = 16)

int16("123456")
1193046
# 使用偏函数实现int16的功能
import functools 
int16Flag = functools.partial(int,base = 16)

int16Flag("12345")
74565

你可能感兴趣的:(Python-学习之路-12 函数式编程-1)