文章目录
函数式编程
高阶函数实例
def test():
print("test function run!!!")
def test_3(a, b):
print(f"test_03, {a}, {b}")
def test_2(func, *args, **kwargs):
print("test_2 function run.....")
func(*args, **kwargs)
a = test
test_2(a)
test_2(test_3, 100, 200)
上面这段代码定义了三个函数:test
、test_3
和 test_2
。test
和 test_3
是简单的打印函数,而 test_2
是一个高阶函数,它接受一个函数作为参数,并调用这个函数。
下面是对代码中每一部分的详细注释:
def test():
# 这个函数当被调用时,会打印一条消息。
print("test function run!!!")
def test_3(a, b):
# 这个函数接受两个参数a和b,并打印它们。
print(f"test_03, {a}, {b}")
def test_2(func, *args, **kwargs):
# 这个高阶函数接受一个函数作为第一个参数func,随后的参数是任意数量的位置参数(args)和关键字参数(kwargs)。
print("test_2 function run....")
# 然后调用传入的函数func,同时将args和kwargs中的值传递给func。
func(*args, **kwargs)
# 将test函数赋值给变量a
a = test
# 使用test_2函数调用a,这里的a是之前定义的test函数
test_2(a)
# 使用test_2函数调用test_3函数,并传递两个位置参数100和200
test_2(test_3, 100, 200)
当这段代码执行时,其行为如下:
- 定义了
test
函数,它只打印一条消息。 - 定义了
test_3
函数,它接受两个参数并打印出来。 - 定义了
test_2
函数,这是一个高阶函数,它接受一个函数和其他任意数量的参数,然后调用这个函数,并将其他参数传递给它。 - 将
test
函数赋值给变量a
。 - 调用
test_2
函数,传递a
作为第一个参数。由于a
是test
函数,所以test
函数将被调用,打印出 “test function run!!!”。 - 再次调用
test_2
函数,这次传递test_3
作为第一个参数,并且传递了两个位置参数100和200。test_3
函数将被调用,并且打印出 “test_03, 100, 200”。
这个示例展示了如何在Python中使用函数作为参数,以及如何利用可变参数列表(*args
和 **kwargs
)来提高函数的灵活性。
高阶函数和内存分析
-
高阶函数: 一个函数可以接收另一个函数作为参数,eg:
map
、reduce
、filter
、sorted
lambda表达式
可以用来声明
匿名函数
,lambda
函数实际生成了一个函数对象lambda
表达式只允许包含一个表达式,该表达式的计算结果就是函数的返回值f = lambda a, b: a+b print(type(f)) # <class 'function'> print(f(1, 2)) # 3 g = [lambda a: a*2, lambda b: b*3, lambda c: c*4] print(g[0](5), g[1](5), g[2](5)) # 10 15 20
偏函数
作用是把一个函数某些属性固定住(设默认值),返回新函数
def int2(x, base=2):
return int(x, base)
print(int2("100")) # 4
import functools
int3 = functools.partial(int, base=2)
print(int3("100")) # 4
闭包
闭包是一个函数,只不过这个函数有超能力,可以访问到另一个函数的作用域
函数和自由变量的总和,就是一个闭包
-
闭包的特点:
- 存在内外层函数嵌套的情况
- 内层函数引用了外层函数的变量或者参数(自由变量)
- 外层函数把内层的这个函数本身当做返回值进行返回
-
闭包是指那些能够访问自由变量的函数。
自由变量是指在函数中使用的,既不是参数也不是函数内部定义的变量。
以下是对代码中每一部分的详细注释:
def outer():
# outer函数开始
print("outer")
a = 1 # 定义了一个局部变量a
def inner():
# inner函数开始,它是嵌套在outer函数内部的
print("inner")
# inner函数试图修改outer函数内的变量a
nonlocal a
# 由于inner函数中使用了nonlocal关键字,它告诉Python解释器a是outer函数内的局部变量
# 这样inner函数就可以访问并修改a的值
print(f"a: {a}")
# outer函数返回inner函数的引用,但并未执行inner函数
return inner
# outer函数被调用,返回inner函数的引用,并赋值给变量inn
inn = outer()
# 打印分隔线
print("-----")
# 通过变量inn调用返回的inner函数
# 此时,inner函数被调用,它打印"inner",然后打印变量a的值,该值为1
inn()
当这段代码执行时,其行为如下:
outer
函数被调用,打印 “outer”。- 在
outer
函数内部,定义了一个局部变量a
并赋值为 1。 - 在
outer
函数内部,定义了inner
函数。在inner
函数内部,使用nonlocal
关键字声明了对a
的引用,表明a
是outer
函数的局部变量。 outer
函数执行完毕,返回inner
函数的引用,赋值给变量inn
。- 打印 “-----”。
- 通过变量
inn
调用inner
函数,打印 “inner”,然后打印变量a
的值,该值为 1。
这个例子中的 inner
函数形成了一个闭包,因为它捕获了 outer
函数的一个局部变量 a
。即使 outer
函数执行完毕,由于 inner
函数仍然存在(通过变量 inn
引用),变量 a
也不会被销毁,inner
函数仍然可以访问和修改 a
的值。
闭包内存分析
闭包的作用
-
隐藏变量,避免全局污染
-
可以读取函数内部的变量
闭包的缺点
- 使用不当,导致变量不会被垃圾回收机制回收,造成内存消耗
- 不恰当的使用闭包可能会造成内存泄漏的问题
闭包和自由变量
a = 10 def add(): a = 10 def increment(): nonlocal a a += 1 print("a: ", a) return increment def print_ten(): if a == 10: print("ten!") else: print("全局变量a, 不等于10") increment = add() # increment = increment increment() increment() increment() increment() print_ten()
用闭包实现添加函数功能
def out_func(func): def in_func(*args, **kwargs): print("日志记录 start...") func(*args, **kwargs) print("日志记录 end...") return in_func def func1(): print("使用功能1") def func2(a, b, c): print("使用功能2", a, b, c) func1 = out_func(func1) func1() func2 = out_func(func2) func2(10, 20, 30)
map函数
map函数的应用
def f(x):
return x**2
L = map(f, [1, 2, 3, 4, 5])
print(list(L))
def f(x, y):
return x + y
L = map(f, [1, 2, 3, 4], [10, 20, 30])
# L = map(lambda x, y : x+ y, [1, 2, 3, 4], [10, 20, 30])
print(list(L))
reduce函数
reduce把一个函数作用在一个序列[x1, x2, x3…]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:
from functools import reduce
def add(x, y):
return x + y
sum = reduce(add, [1, 2, 3, 4, 5])
print(sum)
filter函数
内置函数fiter()
用于过滤序列。filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False,决定保留还是丢弃该元素。
filter过滤列表,删掉偶数,只保留奇数
def is_odd(n):
return n % 2 == 1
L = filter(is_odd, [1, 2, 4, 5])
# L = filter(lambda x: x % 2 == 1, [1, 2, 4, 5])
print(list(L))
sorted函数
class Student:
def __init__(self, name, age):
self.name = name
self.age = age
stu1 = Student("aaa", 41)
stu2 = Student("ccc", 21)
stu3 = Student("bbb", 31)
student_list = sorted([stu1, stu2, stu3], key=lambda x: x.age)
for stu in student_list:
print(f"{stu.name}---{stu.age}")
"""
ccc---21
bbb---31
aaa---41
"""