递归函数
- 递归函数 自己调用自己,必须要找到函数停止的条件
# 递归 函数内部自己调用自己
# 递归的关键是找到程序的出口(程序停止的条件)
# 使用count 计数器
count = 0
def tell_story():
global count
count += 1
print('hello world')
if count < 5:
tell_story()
tell_story()
# 求 n 个数的和
def get_sum(n):
if n == 0:
return 0
return get_sum(n - 1) + n
# 关键是要停下来
print(get_sum(6))
匿名函数
- 用来表示简单的函数,调用次数很少
- 省略了需要 def 声明函数部分
语法
- lambda 参数列表:运算符表达式
def add(a, b):
return a + b
x = add(2, 5)
fn = add # 相当于给函数fn 起一个别名
print(fn(2, 3))
# lambda 定义一个函数
# 匿名函数 用来表示简单的函数,调用次数很少基本上只用一次
# 调用匿名函数的方式
# 1.给他定义一个名字(很少使用)
mul = lambda a, b: a + b
print(mul(2, 3))
使用场景
把匿名函数当作参数传递给另一个函数
# 2.把匿名函数当作一个参数传递给另一个函数使用(使用场景比较多)
def add(a,b):
print(a, b)
def clc(a, b, obj):
print(a, b, obj)
obj = lambda a, b: add(a, b)
clc(1, 2, (3, 4))
高阶函数
- 把函数当成数字和字符串使用
- 一个函数当作另一个函数的参数
- 函数作为返回值
- 函数中写另一个函数
# 1.一个函数作为另一个函数的参数
# 2.一个函数作为另一个函数的返回值
# 3.在一个函数中写另一个函数
def foo():
print(1)
return 'foo'
def bar():
print(2)
return foo
x = bar()
print('x的值是{}'.format(x))
print('-----------------')
x()
bar()() # 调用bar · bar再调用foo
def outer():
m = 100
def inner():
n = 98
print('我是inner函数')
inner()
print('我是outer函数')
return inner
# inner()函数在外部不能使用
outer()() # 先调用outer 再在outer内部调用inner
闭包的使用
- 闭包函数 = 名称空间与作用域+函数嵌套+函数对象
def outer(n):
num = n
def inner():
return num+1
return inner
print(outer(1)()) # 2
print(outer(5)()) # 6
闭包函数定义:在一个函数中包含一个函数对其作用域的外部变量的引用,那个对外部函数引用的函数为闭包
# 1.大前提
# 闭包函数 = 名称空间与作用域+函数嵌套+函数对象
# 核心点:名字的查找关系是以函数定义阶段为准的
# 2.什么是闭包函数
# 闭 指函数定义在一个函数内的函数(内嵌函数)
# 包 指函数对包含在外层的函数的作用域的名字的引用
# (不包含全局作用域)
# 闭包函数之名称空间的与作用域的应用 + 函数嵌套
# def f1():
# x = 1
# def f2():
# print(x)
# f2()
# x = 222
# def bar():
# x = 3344
# f1()
#
# bar()
# 闭包函数 :函数对象(以定义阶段为主)
# def f1():
# x = 1
# def f2():
# print('f2的输出',x)
# f2()
#
# return f2 # 返回f2的内存地址
#
# f = f1()
#
# x = 444
# f()
# 3.定义闭包函数
# 4.为何要有闭包函数(闭包函数的应用)
# 两种函数传参方式
# 方式一: 直接把函数体需要的参数定义形参
# def f1(x):
# print(x)
# f1(1)
# 方式二:
def f1():
x = 3
def f2():
print(x)
# f2(x)
return f2
# f2()
f = f1()
f()
- 修改闭包函数中的外部变量 使用 nonlocal函数
def outer(n):
num = n
def inner():
nonlocal num # 修改前使用nonlocal关键字对 num 变量进行说明
num = num + 1
return num
return inner
print(outer(2)())
装饰器的使用
# -*- coding: utf-8 -*-
# @Time : 2021/1/25 21:26
# @File : 装饰器.py
# @Software: PyCharm
# def foo():
# print('foo')
#
#
# foo() # foo
# print(foo) # <function foo at 0x0000027802C19EE0>
# def foo():
# print('foo')
#
#
# foo() # foo
# foo = lambda x: x + 1
# # 把匿名函数赋值给foo之后,原本的函数的内存地址改变为新赋值的
# print(foo) # <function <lambda> at 0x000001C667759A60>
# 开发中要遵循 开放封闭原则
# 封闭 对以开发的功能封闭
# 开放 对扩展的功能开放
# def w1(func):
# def inner():
# # 验证1
# # 验证2
# # 验证3
# func()
# return inner
#
# @w1
# def f1():
# print('f1')
# @w1
# def f2():
# print('f2')
# @w1
# def f3():
# print('f3')
# @w1
# def f4():
# print('f4')
# def w1(func):
# def inner():
# # 验证1
# # 验证2
# # 验证3
# func()
#
# return inner
#
#
# @w1
# def f1():
# print('f1')
# print(f1) # <function w1.<locals>.inner at 0x0000026A3596E4C0>
# 此地址为添加装饰器之后的地址
# @ w1 执行 w1函数, 将 w1下的函数当作参数传递给 w1()函数中的func
# @ w1 ==> w1(f1)
# 此时的func = f1 func() = f1()
def makeBoid(func):
def wrapper():
return '<b>' + func() + '</b>'
return wrapper
def makeIctlin(func):
def wrapper():
return '<a>' + func() + '</a>'
return wrapper
@makeIctlin
def test1():
return '111111'
@makeBoid
def test2():
return '222222'
@makeBoid
@makeIctlin
def test3():
return '3333333'
print(test1())
print(test2())
print(test3())
# <a>111111</a>
# <b>222222</b>
# <b><a>3333333</a></b>
装饰器(decorator)功能
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
无参装饰器
# 无参装饰器
def check(func):
def wrapper():
return '早点' + func()
return wrapper
@check
def go_to_bed():
return '去睡觉'
print(go_to_bed())
# 早点去睡觉
被装饰的函数有参数
def check(func):
def wrapper(name, action):
return '我说' + func(name, action)
return wrapper
@check
def go_to_bed(name, action):
return name + '去睡觉' + action
print(go_to_bed('张三', '在家'))
# 我说张三去睡觉在家
被装饰的函数有不定长参数
def check(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@check
def demo(*args):
sum = 0
for i in args:
sum += i
print(sum)
print(demo(1, 2, 3))