函数基础知识
递归函数
- 函数的返回值是函数自身
- 用于解决可以拆分的大问题
递归函数的条件
- 递归条件:问题可以被继续分解
- 基线条件:问题最小化时返回一个确切的值,并停止递归
例题1:判断回文字符串
def Palindrome(str1):
if len(str1) < 2:
return '该字符串是回文字符串'
elif str1[0] != str1[-1]:
return '该字符串不是回文字符串'
return Palindrome(str1[1:-1])
str1 = input('请输入任意字符串:')
print(Palindrome(str1))
# ----------输出----------
# 请输入任意字符串:asddsa
# 该字符串是回文字符串
例题2:汉诺塔问题
def Hanoi(num, A, B, C):
if num == 1:
print(f'{A}->{C}')
elif num > 1:
Hanoi(num-1, A, C, B) # 将上面的 n-1 个汉诺塔,从 A 经过 C 挪到 B
print(f'{A}->{C}') # 再将地下的最后一个汉诺塔,从 A 挪到 B
Hanoi(num-1, B, A, C) # 最后将 B 上的 n-1 个汉诺塔,从 B 经过 A 挪到 C
num = int(input('请输入汉诺塔的数量:'))
Hanoi(num, 'A', 'B', 'C')
# ----------输出----------
# 请输入汉诺塔的数量:3
# A->C, A->B, C->B, A->C, B->A, B->C, A->C,
高阶函数
- 以函数名作为参数或返回值的函数。eg:递归函数
- eg:filter ( ) 函数 - - - 过滤可迭代序列
- 参数:起判断作用的函数 & 需要过滤的序列
- 返回值:过滤后的序列
def fun1(value):
if value % 3: # 过滤掉3的倍数
return True
return False
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(tuple(filter(fun1, list1)))
# ----------输出----------
# (1, 2, 4, 5, 7, 8)
匿名函数
- lambda 形参 :返回值 - - - 相当于一个函数名。
- 如果后面要跟实参的话,需要用圆括号包裹
sum = (lambda value1, value2 : value1 + value2)(3, 5)
print(sum)
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
filtration = lambda value : value % 3
print(list(filter(filtration, list1)))
# ----------输出----------
# 8
# [1, 2, 4, 5, 7, 8]
闭包
闭包形成的条件
- 有函数的嵌套
- 外部函数的返回值是内部函数名
- 内部函数使用到外部函数的变量 / 参数
闭包的特点
- 外部函数的变量是只能作用于闭包内的全局变量
- 闭包内的变量只有当前闭包能访问
def average():
list1 = []
def calculation(num):
list1.append(num)
return sum(list1) // len(list1)
return calculation
ave = average()
print(ave(10), end=', ')
print(ave(20))
# ----------输出----------
# 10, 15
nonlocal 关键字
使用 nonlocal 声明内嵌函数的变量,就可以修改外部函数的同名变量;否则内嵌函数的变量会覆盖外部函数的同名变量
def funOut(num1):
def funIn(num2):
nonlocal num1
num1 = 10
result = num1 + num2
return result
print(num1, end=' - ')
print(funIn(num1), end=' - ')
print(num1, end=' - ')
return funIn
f = funOut(1)
print(f(5))
# ----------输出----------
# 1 - 11 - 10 - 15
装饰器
- 装饰器可以在不修改原函数的情况下,对函数的功能进行扩展,符合开闭原则。
- 开闭原则 (OCP) :在程序设计中,要求在不修改原代码块的基础上,拓展程序的功能
- 装饰器就是一个闭包
一般写法
def Add(num1, num2):
return num1 + num2
def expandFun(oldFun):
def newFun(*args, **kwags):
print('我是扩展的功能', end=' - ')
return oldFun(*args, **kwags)
return newFun
print(Add(1, 2))
newAdd = expandFun(Add)
print(newAdd(1, 2))
# ----------输出----------
# 3
# 我是扩展的功能 - 3
思路:设计一个专门用来拓展功能的装饰器,我们就可以把原函数的函数名作为形参传给装饰器,装饰器就会对该函数进行功能拓展,并返回拓展后的新函数的函数名。
语法糖写法
- 在原函数定义前 @ 装饰器名,即可给原函数添加上拓展功能。
- @装饰器名 - - - 原函数名 = 装饰器名 ( 原函数名 )
def expandFun(oldFun):
def newFun(*args, **kwags):
print('我是扩展的功能', end=' - ')
return oldFun(*args, **kwags)
return newFun
@expandFun # 相当于 Add = expandFun(Add)
def Add(num1, num2):
return num1 + num2
print(Add(1, 2))
# ----------输出----------
# 我是扩展的功能 - 3