文章目录
函数式编程和 高阶函数
# 函数式编程和 高阶函数
# 高阶函数
1. 变量可以指向函数本身
2. 函数名 也是变量
# 示例
# 求-10 的绝对值
print(abs(-10))
print(abs)
# abs 是指向一个函数,也就是函数本身
# abs () 指的是对函数的调用
f=abs # f 变量也是指向abs 所指向 的函数
f(-10) # 可以通过该 变量来调用这个函数
# 结论: 变量 f 指向了 abs 函数本身
# 函数名 也是变量
# 函数名 其实就是指向函数的变量, 对于abs(0 )这个函数 ,我们可以
# 把函数名 abs 看成是 一个变量, 他指向计算绝对值的函数
abs=10
print(abs(-10))#这 样就会抛出异常
# 实际使用中 变量 名 命名 是不能这样写的,是为了 说明函数名 也是一个变量
既然变量可以指向函数,函数的参数 能接收变量,那么一个函数就可以接收另外一个函数 作为参数
, 这种函数就称之为 高阶函数
# 简单示例 高阶函数
def add (x,y,f):
return f(x)+f(y)
print(add(-110,5,abs))
# 这样的话 就是 一个 高阶函数的使用
# 函数式编程
'把函数作为参数传入', 这样的函数称为高阶函数, '函数式编程'就是指这种高度抽象的编程范式。
Python 内建的高阶函数有 map、 reduce、 filter、 sorted。
map
map 函数
map()函数接收两个参数, 一个是函数, 一个是序列,
map 将传入的函数依次作用到序列的每个元素, 并把结果作为新的 list 返回。实际上是一个 map 对象
也就是映射
# map 函数示例
# 传递两个列表
'''
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
'''
a=[1,2,3,4]
b=[10,20,30]
def f(x,y):
return x+y
L=map(f,a,b)
print(list(L))
# 判断是否是可迭代对象
from collections import Iterator
print('判断是否是可迭代的:',isinstance(L,Iterator))
# python 内置函数教程 菜鸟教程
# https://www.runoob.com/python/python-built-in-functions.html
# 传统的实现方法
def g(x):
return x * x
result_list = []
for i in a:
result_list.append(g(i))
print(result_list)
# map 的实现方式
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
def g(x):
return x * x
def map_(func,a):
return (func(i) for i in a)
c = list(map_(g, a))
print(c)
运行结果
# 将列表中的 每个元素 转换成字符串
'''
map(func, *iterables) --> map object
Make an iterator that computes the function using arguments from
each of the iterables. Stops when the shortest iterable is exhausted.
'''
a = [1, 2, 3, 4, 5, 6, 7, 8, 9] #将列表中每个元素转换为字符串
L = map(str, a)
print(list(L))
reduce
reduce 函数
把一个函数作用在一个序列[x1, x2, x3...]上, 这个函数必须接收两个参数,
reduce 把结果继续和序列的下一个元素做累积计算,
其效果就是:
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
# reduce 的实现
def reduce_(func,a,init=None):
if init is None:
tmp_a=a
else:
tmp_a=[init,*a]
pre_cur=[]
while len(tmp_a)>1:
pre_cur=tmp_a[:2]
tmp_a=tmp_a[1:]
tmp_a[0]=func(pre_cur[0],pre_cur[1])
return tmp_a[0]
def foo(x,y):
return x+y
a=[1,2,3,4,5,6,7,8,9,10]
sum_=reduce_(foo,a,)
[in] : sum_
[out] : 55
---------------------------
a=[1,2,3,4,5,6,7,8,9,10]
sum_=reduce_(foo,a,10)
# 当然这种 高阶函数中简单的函数 可以用 lambda 函数代替。
# reduce_(lambda x,y:x+y,a,10)
# 10 是初始值。 如果设置了 那么 x 就是 10
# 没有设置的话 。 x 是 a[0] y是 a[1]
# 然后计算后返回值 作为 x 下一个元素。 作为 a[1]
# reduce_ 也可以使用递归来实现
# 有兴趣的 可以自己写着 玩。
[in]: sum_
[out]: 65
# 高阶函数 reduce
from functools import reduce
# 计算一个序列的求和
a=[1,2,3,4,5,6,7,8,9,10]
# 普通方法
sum_=0
for i in a:
sum_+=i
print('累加和:',sum)
# reduce 方法
def sumTest(x,y):
return x+y
sum=reduce(sumTest,a)
print('reduce计算列表求和:',sum)
# 当然纯粹的 求和的话 sum(a) 就好了
# reduce 的使用方法
from functools import reduce
# 把序列[1, 3, 5, 7, 9]变换成整数13579。将列表中的每个元素乘以10加上后一个元素。
a=[1, 3, 5, 7, 9]
def fun(x,y):
return x*10+y
result=reduce(fun,a)
print(result)
# 当然以解决问题的想法的话
int(''.join(map(str,a))) # 这个更加符合我们的需求
初始化参数
类似于这种 循环的时候 需要 创建 中间变量的都可以使用 这个 可选的 initial
参数。
来使用 reduce
完成 常见的循环操作。
a_string='i like python, javascript, go'
b_li=['python', 'javascript', 'go']
reduce(lambda pre,next_:pre.replace(next_,f"<a>{next_}</a>"),b_li,a_string)
# b_li 就是我们传递进去的 序列。
# a_string 是我们的默认值 初始化参数
运行结果
filter
# fileter 的使用
Python 内建的 filter()函数用于过滤序列。 和 map()类似, filter()也接收一个函数和一个序列。
和 map()不同的时, filter()把传入的函数依次作用于每个元素,
然后根据返回值是 True 还是 False 决定保留还是丢弃该元素。
一般都是 返回 True 的值
# filter 函数
# 在一个列表中,删掉偶数,保留奇数
def is_odd(n):
# 求奇数 的函数
# if n%2==0:
# return False
# else:
# return True
return n%2 == 1 # 这种写法比较 好
L=filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
print(list(L))
#一个序列中的空字符串删掉
a=['A', '', 'B', None, 'C', ' ']
def not_empty(s):
return s and s.strip()
L=filter(not_empty,a)
print(list(L))
# 我们自己实现 一下 filter
a=['A', '', 'B', None, 'C', ' ']
def filter_(func,seq):
return [value for value in seq if func(value)]
# 不同的是 我们返回的是 列表
# python 自带的 filter 返回的是一个类似于生成器对象的 东西
# 实现 懒加载。 可以尝试对 filter 使用 next 函数。
def not_empty(s):
return s and s.strip()
filter_(not_empty,a)
运行结果
sorted
sorted 函数
排序算法, 排序也是在程序中经常用到的算法。
无论使用'冒泡排序'还是 '快速排序', 排序的核心是'比较两个元素 '的 '大小'。
如果是数字, 我们可以直接比较, 但如果是'字符串'或者两个 dict 呢?
直接比较数学上的大小是没有意义的, 因此, 比较的过程必须通过函数抽象出来。
通常规定, 对于两个元素 x 和 y, 如果认为 x < y, 则返回-1, 如果认为 x == y,
则返回 0,如果认为 x > y, 则返回 1,
这样, 排序算法就不用关心具体的比较过程, 而是根据比较结果直接排序。
排序函数 实现
def sort_(seq,func):
ran=range(len(seq))
for i in ran:
for j in ran:
if func(seq[i],seq[j])<0:
seq[i],seq[j]=seq[j],seq[i]
return seq
运行结果
x-y 升序
y-x 降序
原理就是 根据 传递的函数 去判断 x-y 小于 0 那么 我就 调换 一个 位置
否则 位置不变。
# sorted( ) 函数的使用
# 1.对数值进行排序
sort_list=sorted([42,422,4,2,-100,3,-10])
print('默认升序排序',sort_list)
# 逆序排序,给sorted添加reverse参数
sort_list=sorted([42,422,4,2,-100,3,-10],reverse=True)
print('逆序',sort_list)
# 对字符串ASCII A:65 a:97
sort_list=sorted(['abc','ad','ABC','D','d','C'])
print('字符串排序',sort_list)
sort_list=sorted(['abc','ad','ABC','D','d','C'],reverse=True)
print('字符串逆序排序',sort_list)
# sorted是高阶函数,他还可以接收一个key函数来实现自定义的排序
# 对数值列表,按绝对值的大小排序
sort_list=sorted([42,422,4,2,-100,3,-10],key=abs)
print('默认升序排序',sort_list)
# 对字符串列表,忽略大小写
sort_list=sorted(['abc','ad','ABC','D','d','C'],reverse=True,key=str.lower)
print('字符串逆序排序',sort_list)
# sorted 函数 使用
# 数值进行 排序
## 默认升序
print(sorted([1, 2, 3, 4, 5, 221, 2, 3, -45]))
## 逆序排序 添加reverse 参数
print(sorted([1, 2, 3, 4, 5, 221, 2, 3, -45], reverse=True))
# 对字符串进行排序 根据 ascii 码 进行排序
print(sorted(['abc', 'DA', 'DAA', 'SDAaa', 'aasdaD', 'ab']))
# sorted 是高阶函数 还可以接受一个key函数 来实现自定义的排序
# 对数值列表进行 绝对值进行排序
print(sorted([1, 2, 3, 4, 5, 221, 2, 3, -45], reverse=True, key=abs))
# 忽略大小写 进行 逆序 也就是降序 排序
print(sorted(['abc', 'ad', 'ABC', 'D', 'd', 'C'], reverse=True, key=str.lower))
需要注意的是 sorted
生成 新的对象。
不对原来的 序列 进行操作。
lambda
函数
匿名函数 lambda 函数
在传入函数时, 有些时候, 不需要显式地定义函数, 直接传入匿名函数更方便。
在 Python 中, 对匿名函数提供了支持。 计算 f(x)=x2 时, 除了定义一个 f(x)的函数外,
还可以直接传入匿名函数。 使用 lambda 可以声明一个匿名函数。
lambda 表达式就是一个简单的函数。 使用 lambda 声明的函数可以返回一个值, 在调用
函数时, 直接使用 lambda 表达式的返回值。
语法格式如下:
lambda arg1,arg2,arg3... : <表达式>
其中 arg1/arg2/arg3 为函数的参数。 <表达式>相当于函数体。 运算结果是: 表达式的运算结果
匿名函数有个限制, 就是只能有一个表达式, 不用写 return, 返回值就是该表达式的结果。
# lambda 函数使用 示例
# lambda arg1,arg2,arg3...:表达式
f=lambda a,b,c:a+b+c
print('调用:',f(3,4,5))
#匿名函数作为map高阶函数的参数 f(x)=x*x
L=map(lambda x:x*x,[1,2,3,4,5,6,7,8,9])
print(list(L))
#sorted中使用匿名函数
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
stu1=Student('zhangsan',21)
stu2=Student('lisi',25)
stu3=Student('wangwu',23)
# result_list=sorted([stu1,stu2,stu3],key=lambda x:x.age)
result_list=sorted([stu1,stu2,stu3],key=lambda x:x.name,reverse=True)
# for stu in result_list:
# print('name:',stu.name,'age:',stu.age)
[print(i.name, i.age) for i in result]
也可是使用 *
进行参数 收集 。d
就是一个容器
闭包
根据字面意思, 可以形象地把闭包理解为一个封闭的包裹, 这个包裹就是一个函数。
当
然, 还有函数内部对应的逻辑, 包裹里面的东西就是自由变量, 自由变量可以随着包裹到处
游荡。
还需要有个前提, 这个包裹是创建出来的。
在 Python 语言中, 闭包意味着要有嵌套
定义
内部函数使用外部函数中定义的变量, 如果调用一个函数 A, 这个函数 A 返回一个
函数 'B', 这个'返回的函数 B '就叫作'闭包'。
什么时候使用闭包?
封装
- 数据隐藏 外部无法访问“嵌套函数”。- 贯彻 DRY(
Don’t Repeat Yourself
) 原则 - 嵌套函数,可以让我们在函数内部
避免重复代码。
- 读取
函数内部变量
- 让函数
常驻内存,以及函数中的变量的值始终保存在内存中
在不修改源代码的情况下添加新的功能
# 闭包的概念
'''
1.什么是闭包
闭包其实就是一个函数
2.如何创建闭包
a.要有函数的嵌套(外部函数、内部函数)
b.内部函数中要使用外部函数的变量
c.外部函数必须有返回值,返回内部函数名
3.如何使用闭包
f=funOut(100) # 调用外部函数,用f变量指向内部函数
print(type(f))
result=f(200) # 通过变量调用函数
'''
# 使用闭包,完成求两个数的和
def sum(a,b):
return a+b
def funOut(num1):
def funIn(num2):
# 内部函数修改外部函数的变量
nonlocal num1
# 忘记了的可以看前面 我写过的。 global 和 nonlocal
num1+=100
return num2+num1
return funIn
# 也可以直接在后面穿参数 很方便
# f = funOut(100)(200)
# print(type(f))
# print(f)
funIn=funOut(100)
print(type(funIn)) # 运行结果 <class 'function'>
result=funIn(200)
print('两个数的和:',result) # 运行结果 两个数的和: 400
# 使用闭包求两点之间的距离
'''
两个点 (x1,y1) (x2,y2)
距离: math.sqrt((x1-x2)**2+(y1-y2)**2)
'''
import math
def getDis(x1,y1,x2,y2):
return math.sqrt((x1-x2)**2+(y1-y2)**2)
# 求点(1,1)距离原点(0,0)的距离
result=getDis(1,1,0,0)
print('点(1,1)距离原点(0,0)的距离',result)
# 求点(2,2)距离原点(0,0)的距离
result=getDis(2,2,0,0)
print('点(2,2)距离原点(0,0)的距离',result)
# 使用闭包求两点之间的距离
def getDisOut(x1,y1):
def getDisIn(x2,y2):
return math.sqrt((x1-x2)**2+(y1-y2)**2)
return getDisIn
# 求点(1,1)距离原点(0,0)的距离
# 调用外部函数
getDisIn=getDisOut(0,0)
result=getDisIn(1,1)
print('点(1,1)距离原点(0,0)的距离',result)
# 求点(2,2)距离原点(0,0)的距离
result=getDisIn(2,2)
print('点(2,2)距离原点(0,0)的距离',result)
这种写法的闭包相当于 将参数 分开 一个函数 传一部分参数进去。
不修改 原有代码的情况下 添加新功能
其实很简单 就是将原有函数
作为参数
传递 给新函数。
# 闭包的特殊用途:不修改源代码的前提下,添加新的功能
# 添加日志输出信息
import time
# 不修改 源代码的情况下 添加新的功能
def writeLog(func):
with open('writeLog.txt', 'a', encoding='utf-8') as f:
f.write('访问:')
f.write(func.__name__)
f.write('\t')
f.write('时间:')
f.write(time.ctime())
f.write('\n')
def fun1():
print('功能1')
def fun2():
print('功能2')
def funOut(func):
def funIn():
writeLog(func)
func()
print('调用的函数:', func.__name__, '结束')
return funIn
fun1 = funOut(fun1)
fun2 = funOut(fun2)
fun1()
fun2()
装饰器
其实装饰器就是闭包
内层函数 和 带装饰器 的函数 处理方法 是一个类型的 至少参数上是大体一致的
在 python 程序中, 装饰器就是一种闭包, 它可以是闭包的访问方式更简单。
在 Python 中使用装饰器, 需要使用一个特殊的符号“@” 来实现。 在定义装饰器函数
或类时, 使用 '@装饰器名称' 的形式将符号 "@" 放在函数或类的定义行之前。
import time
def writeLog(func):
try:
with open('writeLog.txt', 'a', encoding='utf-8') as f:
f.write('访问:')
f.write(func.__name__)
f.write('\t')
f.write('时间:')
f.write(time.ctime())
f.write('\n')
except Exception as e:
print(e.args)
# 使用闭包
def funOut(func):
def funIn():
writeLog(func)
func()
return funIn
@funOut # fun1=funOut(fun1)
def fun1():
print('功能1')
# @funOuT
# 执行过程
# fun2=funOut(fun2) # 需要注意的是 如果 fun2=xxx 这一段,是最后执行。
# 也就是说 装饰器 在完成 最后的 return 之前 fun2 这个变量是不存在的。
# 如果有参数 顺序也是 一样的
# 只是最后加上 a(参数)
# 上述的过程 等于带装饰器的函数 直接 fun2() 或者 有参数的 fun2(参数)
@funOut # 在这里加上 闭包函数的 名字就可以了
def fun2():
print('功能2')
# 不使用装饰器 就需要这样调用 ,还是比较麻烦
# a = funOut(fun1)
# b = funOut(fun2)
# a()
# b()
# 加了装饰器 @ funOut
# 直接这样调用
fun1()
fun2()
# 多个装饰器
# 给foo函数,新增功能
# 在调用foo函数前,输出 ’I am foo‘
# 挨着功能函数最近的装饰器 依次往上 装饰
def funOut(func):
print('装饰器1')
def funIn():
print('I am foo')
func()
return funIn
def funOut2(func):
print('装饰器2')
def funIn():
print('hello')
func()
return funIn
@funOut2
@funOut
def foo():
print('foo函数正在运行')
#使用闭包调用
# foo=funOut(foo)
foo()
带参数的装饰器
# 带参数的装饰器
# def fun1():
# print('功能1')
#
# def foo():
# print('foo函数正在运行')
# 这些装饰器 都是专用的 参数个数要一致
# 不然 其他的 参数个数不一致的 会报错
# 或者 写多个闭包 定制
# 那么还有一个叫做通用装饰器 其实就是 可变参数 忘了的 翻前面的博客。
import time
def writeLog(func):
print('访问了方法名:',func.__name__,'\t时间:',time.asctime())
def funOut(func):
def funIn(x,y):
writeLog(func)
return func(x,y)
return funIn
@funOut
def sum(a,b):
return a+b
result=sum(10,20)
print('两数的和:',result)
# -------------------------------
# 功能函数三个参数
def writeLog(func):
print('访问了方法名:',func.__name__,'\t时间:',time.asctime())
def funOut2(func):
def funcIn(a,b,c):
writeLog(func)
return func(a,b,c)
return funcIn
@funOut2
def add(a,b,c):
return a+b+c
result=add(10,20,30)
print('三个数的和:',result)
通用的装饰器
# args 和 kwargs 的 详细用法
# * 需要元组 ** 需要字典
import time
def funcOut(func):
def funcIn(*args,**kwargs):# 而作为形参的时候 这里是收集 参数
writeLog(func)
return func(*args,**kwargs)# 注意这里 这个 func(*args) 是展开 解包 args 元组
return funcIn
def writeLog(func):
print('访问方法名:',func.__name__,'\t时间:',time.asctime())
# 翻译 为 sum=funcOut(sum)
# 此函数 和 内层函数 fincIn 大体上是一类的函数(个人想法)
@funcOut
def sum(a,b):
return a+b
@funcOut
def add(a,b,c):
return a+b+c
result=sum(10,20)
print('两个数的和:',result)
result=add(10,20,30)
print('三个数的和:',result)
运行 结果
关于 可变参数 的 *
使用 问题
(*args,**kwargs)
上面注释说的问题 就是 下面这个图 要体现的东西。
装饰器传递参数 @route("/index")
url_map={}
def route(option):
def inner(func,*args,**kwargs):
url_map[option]=func
return func(option)
return inner
# 过程
# @route("index")
# 假设赋值的变量为 v
# 1. v=route("/index") 将参数"/index" 传递进route函数,并赋给 一个变量 v,
# 2. v(index) 将index 函数作为参数传入 到 变量 v 上面 .
# 因为 v 其实 就是 route 返回的 inner 函数 。 所以执行的是 inner(index)
@route("/index")
def index(request):
print(f"加载{request}页面")
url_map
整个 运行过程如下:
- 注册对象 url_map
- 注册 route 函数对象
- 执行@route("/index") option 形参 被 赋值 “/index”
- 注册嵌套函数 inner 并 return inner
- 将 func 指向index(request) args 指向 空元组 kwargs 指向 空字典
- 下面就是 执行 inner 内部的命令 将url_map 字典 填充 “/index” 作为键 指向 index(request) 函数
- 执行 func(option) 也就是 执行 index("/index") 这个函数 其中 request 形参 赋值为 “/index”
- 执行 index 函数内部的打印,因为是在 inner 内部执行的 所以 return 的为None 。因为 index 函数没有返回值
- 执行完毕 销毁 内存中 的 inner 函数 inner [parent=f1] 形参赋值 那一步 内存注册赋值的 空间 释放出来。
在类 class 内部使用装饰器
from operator import itemgetter
# 字典多重 排序
class School:
def __init__(self):
self.db = []
def add_student(self, name, grade):
self.db.append({"name": name, "grade": grade})
def sort_db(functi):
def funcin(self, *args):
self.db = sorted(self.db,
key=itemgetter("grade", "name"),
reverse=False)
return functi(self, *args)
return funcin
@sort_db
def roster(self):
return [i['name'] for i in self.db]
@sort_db
def grade(self, grade_number):
return [
i['name']
for i in filter(lambda x: x['grade'] == grade_number, self.db)
]
关于给类加装饰器 其实也是一样的 但是用的比较少。
这里有一个 例子。
利用装饰器 进行父类方法的重写覆盖。
偏函数
# 偏函数
Python 的 functools 模块提供了很多有用的功能, 其中一个就是偏函数(Partial function)。
要注意, 这里的偏函数和数学意义上的偏函数不一样
偏函数是用于对函数固定属性的函数, 作用就是把一个函数某些参数固定住(也就是设
置默认值) , 返回一个新的函数, 调用这个新的函数会更简单。
在介绍函数参数的时候, 我们讲到, 通过设定参数的默认值, 可以降低函数调用的难度。
而偏函数也可以做到这一点。
# 偏函数 示例
print(int('12345')) #将字符串按十进制转换为整数
print('转换为八进制:',int('12345',base=8))
print('转换为十六进制:',int('12345',16))
#将'1010' 按二进制转换为整数
print(int('1010',base=2))
print(int('101010',base=2))
print(int('10101010',base=2))
#定义函数
def new_int(s):
return int(s,base=2)
print(new_int('1010'))
print(new_int('101010'))
print(new_int('10101010'))
from functools import partial
new_int=partial(int,base=2)
print(new_int('1010'))
print(new_int('101010'))
print(new_int('10101010'))
一个例子
关于让 实例对象可迭代。
可以循环
使用 偏函数 进行默认值的设置。
from functools import partial
class Student:
def __init__(self,name,id_):
self.name=name
self.id_=id_
@property
def description(self):
print(f"name:{self.name}\nid:{self.id_}")
def __iter__(self):
travel=partial(self.travel,reverse=True)
return travel()
def travel(self,reverse=False):
result=list(self.__dict__.items())
if reverse:
return iter(result[::-1])
return iter(result)
一些运行效果。
高阶函数 和 递归的一些例子
# 平方
def square(x):
return x*x
# 立方
def cube(x):
return pow(x,3)
# 立方和
def sum_square(x,y):
return square(x)+square(y)
# 求 a到 b 之间的和 线性迭代 计算过程
def sum_integers_iteration(a,b):
total=0
while a<=b:
a,total=a+1,total+a
return total
# 求 a到 b 之间的和 线性递归计算过程
def sum_integers_recursion(a,b):
if a>b:
return 0
else:
return a+sum_integers_recursion(a+1,b)
# 求连续立方和 线性递归过程
def sum_cubes_recursion(a,b):
if a>b:
return 0
else:
return pow(a,3)+sum_cubes_recursion(a+1,b)
# 求 连续序列 8/pi 最后向pi 收拢
def sum_pi_recursion(a,b):
if a>b:
return 0
else:
return 8/(a*(a+2))+sum_pi_recursion(a+4,b)
递归公共模式
# 递归公共模式
def public_recursion_summation(term,a,_next,b):
if a>b:
return 0
else:
return term(a)+ public_recursion_summation(term,_next(a),_next,b)
# 递归规则
def recursion_successor(x):
return x+1
# 调用公共模式 实现 递归求立方和
def recursion_sum_cubes(a,b):
return public_recursion_summation(cube,a,recursion_successor,b)
线性迭代公共模式
# 求和连续自然数
def sum_naturals(n):
total,k=0,1
while k<=n:
total,k=total+k,k+1
return total
# 求立方和
def sum_cubes(n):
total,k=0,1
while k<=n:
total,k=total+pow(k,3),k+1
return total
# pi 求和 序列
def pi_sum(n):
total,k=0,1
while k<=n:
total,k=total+8/(k*(k+2)),k+4
return total
# 公共模式 接收 上界 n 和 两个函数
def public_summation(n,term,next):
total,k=0,1
while k <= n:
total,k=total+term(k),next(k)
return total
# -------------------------------------------
# 利用公共模式 调用 写出 求连续自然数的 立方和
#
def summation_successor(k):
return k+1
# 公共模式立方和
def sum_cubes(n):
return public_summation(n,cube,summation_successor)
# -----------------------
# 利用 一致函数 返回自己
def identity(k):
return k
# 公共模式 实现 连续求和
def public_sum_naturals(n):
return public_summation(n,identity,summation_successor)
# ------------------------
# 以下 是调用测试。
# sum_naturals(100)
# sum_integers_recursion(1,100)
# sum_integers_iteration(1,100)
# sum_cubes_recursion(1,3)
# 利用公共模式 调用 写出 递归求指定范围数的 立方和
recursion_sum_cubes(1,3)
# 利用公共模式 调用 写出 求连续自然数的 立方和
sum_cubes(3)
# 利用公共模式 调用 写出 求连续自然数的 和
public_sum_naturals(100)