函数式编程基础
函数式编程与面向对象编程一样都是一种编程范式,函数式编程也称为面向函数的编程。Python提供了高阶函数、函数类型和lambda表达式,他们是实现函数式编程的基础。
高阶函数与函数类型
如果一个函数可以作为其他函数的参数或者其他函数的返回值,那么这个函数就是“高阶函数”。任何一个函数的数据类型都是 function 类型,即“函数类型”。
示例代码如下
def calculate_fun():
def add(a,b): #重构了 calculate_fun() 函数
return a+b
return add #返回嵌套函数 add
f = calculate_fun() #将变量f指向 add 函数
print(type(f))
print("10 + 5 = {0}".format(f(10,5)))
代码运行结果
<class 'function'>
10 + 5 = 15
函数作为其他函数返回值使用
可以把函数作为其他函数的返回值使用,下面举个栗子:定义了两个嵌套函数add()和sub(),根据参数返回不同的函数
示例代码如下
def calculate_fun(opr):
def add(a,b): #定义相加函数
return a+b
def sub(a,b): #定义相减函数
return a-b
if opr == '+':
return add
else:
return sub
f1 = calculate_fun('+') #将变量f指向 add 函数
f2 = calculate_fun('-')
print("6 + 12 = {0}".format(f1(6,12)))
print("12 - 6 = {0}".format(f2(12,6)))
代码运行结果
6 + 12 = 18
12 - 6 = 6
函数作为其他函数参数使用
示例代码如下
def calculate_a(value, op): #定义了一个函数,其中 value 是要计算的操作数,op参数是一个函数
return op(value)
def square(n):
return n*n
def abs(n):
return n if n > 0 else -n
print("6的平方 = {0}".format(calculate_a(6,square)))
print("-6的绝对值 = {0}".format(calculate_a(-6,abs)))
代码运行结果
6的平方 = 36
-6的绝对值 = 6
匿名函数与 lambda 表达式
“匿名函数”即在使用的时候不给函数分配名字,在 Python 中用 lambda 表达式表示匿名函数,lambda 是关键字声明(表示这是 lambda 表达式),“参数列表”与函数参数列表相同,但不需要小括号括起来,冒号后面是“lambda体”,类似于函数体。
声明 lambda 表达式的语法如下:
lambda 参数列表: lambda体
注意: lambda体 部分不能是一个代码块,不能包含多条语句,只能有一条语句,语句会计算一个结果返回给 lambda 表达式,但是与函数不同的是,不需要使用 return 语句返回。与其他语言(如Java)中的 lambda 表达式相比,Python中的 lambda 表达式只能提供一些简单的运算。
示例代码如下
def calculate_a(opr):
if opr=='+':
return lambda a,b:(a+b) #替代了add函数,简化代码
else:
return lambda a,b:(a-b) #替代了sub函数,简化代码
f1 = calculate_a('+')
f2 = calculate_a('-')
print(type(f1))
print("6 + 6 = {0}".format(f1(6,6)))
print("6 - 6 = {0}".format(f2(6,6)))
代码运行结果
<class 'function'>
6 + 6 = 12
6 - 6 = 0
函数式编程的三大基础函数
过滤(filter)、映射(map)、聚合(reduce)是处理数据的三大基本操作
过滤函数filter()
可以对可迭代对象的元素进行过滤,filter()函数语法如下:
filter(function,iterable)
其中 function 是一个函数,参数 iterable 是可迭代对象。在filter函数调用时, iterable 会被遍历,它的元素会被逐一传入 function 函数,function 函数返回布尔值。在 function 函数中编写过滤条件,结果为True 的元素会被保留,结果为 False 的函数会被过滤掉。
示例代码如下
users = ['Tony','Tom','jack','Tome']
users_filter = filter(lambda u:u.startswith('T'),users)
# 过滤条件为T开头的元素,lambda u:u.startswith('T')是一个lambda表达式
# filter函数不是列表,需要使用list函数转化为列表
print(list(users_filter))
print("示例2:")
'''下面示例实现了获取1~20中能被3整除的数'''
number_list = range(1,21)
number_filter = filter(lambda it:it % 3 == 0,number_list)
print(list(number_filter))
代码运行结果
['Tony', 'Tom', 'Tome']
示例2:
[3, 6, 9, 12, 15, 18]
映射函数map()
可以对可迭代对象的元素进行变换,map()函数语法如下:
map(function,iterable)
示例代码如下
users = ['Tony','Tom','jack','Tome']
users_map = map(lambda u:u.lower(),users)
print(list(users_map))
print("使用过滤器和map的示例2:")
'''
函数式编程时数据可从一个函数流入另外一个函数,但遗憾的是Python并不支持“链式”API
因此在实现“获取T开头的字母,再将其转换为小写字母”这样的需求时
需要使用filter函数进行过滤再用map进行映射变换
'''
users = ['Tony','Tom','jack','Tome']
users_filter = filter(lambda u:u.startswith('T'),users)
users_map = map(lambda u:u.lower(),users_filter)
# users_map = map(lambda u:u.lower(),filter(lambda u:u.startswith('T'),users))
# 该段代码实现和上面一样的效果,但是可读性则不是很好
print(list(users_map))
代码运行结果
['tony', 'tom', 'jack', 'tome']
使用过滤器和map的示例2:
['tony', 'tom', 'tome']
聚合函数reduce()
聚合操作会将多个数据聚合起来输出单个数据,reduce()函数会将多个数据按照指定的算法积累叠加起来,最后输出一个数据,reduce()函数语法如下:
reduce(function,iterable[,initializer])
参数 function 是聚合操作函数,iterable 是可迭代对象, initializer 是初始值,接下来通过一个示例实现对一个数列的求和运算
示例代码如下
from functools import reduce
#导入functools模块,因为reduce是在functools模块中定义的
a = (3,4,5,6)
a_reduce = reduce(lambda acc,i:acc+i ,a)
print(a_reduce)
b = (3,4,5,6)
b_reduce = reduce(lambda acc,i:acc+i ,b,2)
print(b_reduce)
代码运行结果
18
20
装饰器
装饰器是一种设计模式,就是在不修改函数代码的情况下,给函数增加一些功能
使用装饰器
Python提供了装饰器注释功能,使用 @方法名 装饰器声明。一个函数可以有多个装饰器声明。
示例代码如下
def uppercase_decorator(func):
def inner():
s = func()# 调用原始函数
make_uppercase = s.upper()# 将结果转换为大写
return make_uppercase
return inner
def bracket_decorator(func):
def inner():
s = func()# 调用原始函数
make_bracket = '['+s+']'# 将结果前后加上方括号
return make_bracket
return inner
#使用装饰器装饰 say_hello 函数
@bracket_decorator
@uppercase_decorator
def say_hello():
return 'hello world.'
print(say_hello())
say_hello
函数首先被 uppercase_decorator
装饰,然后是 bracket_decorator
。这意味着 say_hello
函数被 uppercase_decorator
包裹,返回的函数再被 bracket_decorator
包裹。
say_hello()
调用bracket_decorator
的inner
函数。- 这个
inner
函数再调用uppercase_decorator
的inner
函数。 - 最后,
uppercase_decorator
的inner
函数调用原始的say_hello
函数,获取字符串 'hello world.',转换为大写,然后返回给bracket_decorator
的inner
函数。 bracket_decorator
的inner
函数将结果加上方括号,然后返回
代码运行结果
[HELLO WORLD.]
给装饰器传递参数
装饰器本质上是一个函数,因此可以给装饰器传递参数
示例代码如下
def calc(func): # 它的参数还是一个函数
def wrapper(arg1): #定义嵌套函数,其参数列表(arg1)与装饰器要注释的函数参数列表一致
return func(arg1)
return wrapper
@calc
def square(n):
return n*n
@calc
def abs(n):
return n if n>0 else -n
print("6的平方 = {0}".format(square(6)))
print("-6的绝对值 = {0}".format(abs(-6)))
代码运行结果
6的平方 = 36
-6的绝对值 = 6
标签:return,函数,Python,编程,filter,print,def,lambda
From: https://blog.csdn.net/2302_76708905/article/details/139708507