文章目录
- 函数
- 1 函数基础
- 1.1 函数三要素与作用
- 1.2 作用域
- 1.2.1 LEGB原则
- 1.2.3 命名空间
- 2 匿名函数
- 2.1 一个需求
- 2.2 lambda
- 2.3 匿名函数应用
- 2.3.1 列表排序
- 2.3.2 字典列表排序
- 3 函数式编程
- 3.1 map函数
- 3.2 reduce函数
- 3.3 fliter函数
- 4 递归函数
- 4.1 递归基本原理
- 4.2 阶乘实现
- 4.3 斐波那契数列
- 4.4 遍历多维列表
- 5 闭包
- 5.1 基本概念
- 5.2 闭包理解
- 5.3 闭包使用场景
- 5.3.1 n次幂计算
- 5.3.2 闭包使用场景
- 5.3.3 __closure__属性
- 6 装饰器
- 6.1 再看闭包
- 6.2 使用装饰器
- 6.3 wraps
- 7 yield与生成函数
- 7.1 带yeild关键字函数者;
- 7.2 yield使用场景
- 7.3 send方法
函数
1 函数基础
1.1 函数三要素与作用
-
函数名
遵循规则:小写字母与下划线组成
def funcname(args):pass
-
函数参数
参数类型:无参,有参,带默认值参数,可变长参数
# 无参函数
import time
def get_timestamp():return time.time()
get_timestamp()
1695367866.906982
# 形式参数
#1个参数函数
def str_to_int(s):if s.strip():return int(s.strip())return 0
#2个参数函数
def my_add(x, y):return x+ynum = str_to_int("10")
res = my_add(10, 20)
print(num, res)
10 30
# 带默认值参数
#默认十进制
def str_to_int(s, base = 10):value = int(s, base)return value
#十进制,逢十进一
base_10 = str_to_int("10")
#二进制,逢二进一
base_2 = str_to_int("10",base = 2)
print(base_10, base_2)
10 2
#位置参数与关键字参数
#定义求余函数
def calculate_remainder(m, n):return m%n
#位置参数
print(calculate_remainder(10,3))
#关键字参数
print(calculate_remainder(n = 3, m = 10))
1
1
# 可变长非关键字参数
print(min(1,2,3,5))
print(min(5,6,7))
1
5
def func(*args):print("*args value:", args)print("*args type :", type(args))print("*args拆包后:", *args)
func(1,2,3)
*args value: (1, 2, 3)
*args type : <class 'tuple'>
*args拆包后: 1 2 3
# 定义一个函数,分别求给定数据的最大值与最小值
def count_max_min(x, y, *args):max_val = max(x, y, *args)min_val = min(x, y, *args)print(max_val, min_val)listv = list(range(10))
#调用时拆包;
#调用时打包为元组;
count_max_min(1,2,*listv)
9 0
# 可变长关键字参数
#定义方式:
def func(**kwargs):print("**kwargs value:", kwargs)print("**kwargs type :", type(kwargs))print("*kwargs:", *kwargs)
#调用方式
func(name="sun", age=10)
**kwargs value: {'name': 'sun', 'age': 10}
**kwargs type : <class 'dict'>
*kwargs: name age
def test(**kwargs):func(**kwargs)dinfo = {"name":"sun", "age":10}
#调用test时候进行拆包为关键字参数
#执行中test将其打包成字典
test(**dinfo)
**kwargs value: {'name': 'sun', 'age': 10}
**kwargs type : <class 'dict'>
*kwargs: name age
#函数参数陷阱
#listv默认值列表
def test_func(value, listv = []):print(id(listv))listv.append(value)return listv
glist = []
v1 = test_func(1, glist)
v2 = test_func(2)
v3 = test_func(3)print(v1, id(v1))
print(v2, id(v2))
print(v3, id(v3))
2178159453632
2178159523200
2178159523200
[1] 2178159453632
[2, 3] 2178159523200
[2, 3] 2178159523200
- 函数返回值,默认返回None
#默认返回值
def func():pass
res = func()
print(res, type(res))
None <class 'NoneType'>
# return返回单个结果
def foo(x, y):return x+yres = foo(10, 20)
print(res)
30
# 返回多个对象
def count_max_min(x,y,*args):max_val = max(x, y, *args)min_val = min(x, y, *args)return max_val, min_valres = count_max_min(10, 20, 2,3,4,5)
print(res)
max_value, min_value = count_max_min(10, 20, 2,3,4,5)
print(max_value, min_value)
(20, 2)
20 2
1.2 作用域
作用域:变量在程序中的可应用范围
引入作用域操作:定义函数,类
1.2.1 LEGB原则
-
L:Local——(函数内部)局部作用域
-
E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)
-
G:Global——(模块全局)全局作用域
-
B:Buildin ——(内建)内建作用域
Python查找变量的规则:LEGB;
Local-->Enclosed-->Global-->Builtin
x = 10
def func():x = 1print("in func x:", x)
func()
print("out func x:", x)
in func x: 1
out func x: 10
1.2.3 命名空间
命名空间(Namespace):实质名称到对象的映射,便于变量的查找;
局部命名空间(函数:local namespace):函数参数与局部变量
模块命名空间(全局:globalnamespace):全局变量,函数,导入模块等
内置命名空间(内置:build-in):内置函数及异常信息
x = 10000
def func():x = 1print("in func x:", x)print("locals:", locals())
func()
print("out func x:", x)
print("globals:", globals())
in func x: 1
locals: {'x': 1}
out func x: 10000
globals: {'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'def funcname(args):\n pass', '# 无参函数\nimport time\ndef get_timestamp():\n return time.time()\nget_timestamp()', '# 形式参数\n#1个参数函数\ndef str_to_int(s):\n if s.strip():\n return int(s.strip())\n return 0\n#2个参数函数\ndef my_add(x, y):\n return x+y\n\nnum = str_to_int("10")\nres = my_add(10, 20)\nprint(num, res)', '# 带默认值参数\n#默认十进制\ndef str_to_int(s, base = 10):\n value = int(s, base)\n return value\n#十进制,逢十进一\nbase_10 = str_to_int("10")\n#二进制,逢二进一\nbase_2 = str_to_int("10",base = 2)\nprint(base_10, base_2)', '#位置参数与关键字参数\n#定义求余函数\ndef calculate_remainder(m, n):\n return m%n\n#位置参数\nprint(calculate_remainder(10,3))\n#关键字参数\nprint(calculate_remainder(n = 3, m = 10))', '# 可变长非关键字参数\nprint(min(1,2,3,5))\nprint(min(5,6,7))', 'def func(*args):\n print("*args value:", args)\n print("*args type :", type(args))\n print("*args拆包后:", *args)\nfunc(1,2,3)', 'def count_max_min(x, y, *args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 定义一个函数,分别求给定数据的最大值与最小值\ndef count_max_min(x, y, *args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 可变长关键字参数\n#定义方式:\ndef func(**kwargs):\n print("**kwargs value:", kwargs)\n print("**kwargs type :", type(kwargs))\n print("*kwargs:", *kwargs)\n#调用方式\nfunc(name="sun", age=10)', 'def test(**kwargs):\n func(**kwargs)\n\ndinfo = {"name":"sun", "age":10}\n#调用test时候进行拆包为关键字参数\n#执行中test将其打包成字典\ntest(**dinfo)', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#默认返回值\ndef func():\n pass\nres = func()\nprint(res, type(res))', '# return返回单个结果\ndef foo(x, y):\n return x+y\n\nres = foo(10, 20)\nprint(res)', '# 返回多个对象\ndef count_max_min(x,y,*args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n return max_val, min_val\n\nres = count_max_min(10, 20, 2,3,4,5)\nprint(res)\nmax_value, min_value = count_max_min(10, 20, 2,3,4,5)\nprint(max_value, min_value)', '### 1.2 作用域\n作用域:变量在程序中的可应用范围\n\n引入作用域操作:定义函数,类\n\n#### 1.2.1 LEGB原则\n1. L:Local——(函数内部)局部作用域\n\n2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)\n\n3. G:Global——(模块全局)全局作用域\n\n4. B:Buildin ——(内建)内建作用域', 'x = 10\ndef func():\nx = 1\nprint("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 100000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 10000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())'], '_oh': {2: 1695367866.906982}, '_dh': [WindowsPath('d:/study/code/jupyter/PythonLearning')], 'In': ['', 'def funcname(args):\n pass', '# 无参函数\nimport time\ndef get_timestamp():\n return time.time()\nget_timestamp()', '# 形式参数\n#1个参数函数\ndef str_to_int(s):\n if s.strip():\n return int(s.strip())\n return 0\n#2个参数函数\ndef my_add(x, y):\n return x+y\n\nnum = str_to_int("10")\nres = my_add(10, 20)\nprint(num, res)', '# 带默认值参数\n#默认十进制\ndef str_to_int(s, base = 10):\n value = int(s, base)\n return value\n#十进制,逢十进一\nbase_10 = str_to_int("10")\n#二进制,逢二进一\nbase_2 = str_to_int("10",base = 2)\nprint(base_10, base_2)', '#位置参数与关键字参数\n#定义求余函数\ndef calculate_remainder(m, n):\n return m%n\n#位置参数\nprint(calculate_remainder(10,3))\n#关键字参数\nprint(calculate_remainder(n = 3, m = 10))', '# 可变长非关键字参数\nprint(min(1,2,3,5))\nprint(min(5,6,7))', 'def func(*args):\n print("*args value:", args)\n print("*args type :", type(args))\n print("*args拆包后:", *args)\nfunc(1,2,3)', 'def count_max_min(x, y, *args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 定义一个函数,分别求给定数据的最大值与最小值\ndef count_max_min(x, y, *args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '# 可变长关键字参数\n#定义方式:\ndef func(**kwargs):\n print("**kwargs value:", kwargs)\n print("**kwargs type :", type(kwargs))\n print("*kwargs:", *kwargs)\n#调用方式\nfunc(name="sun", age=10)', 'def test(**kwargs):\n func(**kwargs)\n\ndinfo = {"name":"sun", "age":10}\n#调用test时候进行拆包为关键字参数\n#执行中test将其打包成字典\ntest(**dinfo)', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '#默认返回值\ndef func():\n pass\nres = func()\nprint(res, type(res))', '# return返回单个结果\ndef foo(x, y):\n return x+y\n\nres = foo(10, 20)\nprint(res)', '# 返回多个对象\ndef count_max_min(x,y,*args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n return max_val, min_val\n\nres = count_max_min(10, 20, 2,3,4,5)\nprint(res)\nmax_value, min_value = count_max_min(10, 20, 2,3,4,5)\nprint(max_value, min_value)', '### 1.2 作用域\n作用域:变量在程序中的可应用范围\n\n引入作用域操作:定义函数,类\n\n#### 1.2.1 LEGB原则\n1. L:Local——(函数内部)局部作用域\n\n2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)\n\n3. G:Global——(模块全局)全局作用域\n\n4. B:Buildin ——(内建)内建作用域', 'x = 10\ndef func():\nx = 1\nprint("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 100000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', 'x = 10000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())'], 'Out': {2: 1695367866.906982}, 'get_ipython': <bound method InteractiveShell.get_ipython of <ipykernel.zmqshell.ZMQInteractiveShell object at 0x000001FB246700D0>>, 'exit': <IPython.core.autocall.ZMQExitAutocall object at 0x000001FB24673850>, 'quit': <IPython.core.autocall.ZMQExitAutocall object at 0x000001FB24673850>, 'open': <function open at 0x000001FB22316AC0>, '_': 1695367866.906982, '__': '', '___': '', '__session__': 'd:\\study\\code\\jupyter\\PythonLearning\\Untitled.ipynb', '_i': 'x = 100000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_ii': 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_iii': 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\nfunc()\nprint("out func x:", x)', '_i1': 'def funcname(args):\n pass', 'funcname': <function funcname at 0x000001FB24682340>, '_i2': '# 无参函数\nimport time\ndef get_timestamp():\n return time.time()\nget_timestamp()', 'time': <module 'time' (built-in)>, 'get_timestamp': <function get_timestamp at 0x000001FB24682020>, '_2': 1695367866.906982, '_i3': '# 形式参数\n#1个参数函数\ndef str_to_int(s):\n if s.strip():\n return int(s.strip())\n return 0\n#2个参数函数\ndef my_add(x, y):\n return x+y\n\nnum = str_to_int("10")\nres = my_add(10, 20)\nprint(num, res)', 'str_to_int': <function str_to_int at 0x000001FB24682DE0>, 'my_add': <function my_add at 0x000001FB24681F80>, 'num': 10, 'res': (20, 2), '_i4': '# 带默认值参数\n#默认十进制\ndef str_to_int(s, base = 10):\n value = int(s, base)\n return value\n#十进制,逢十进一\nbase_10 = str_to_int("10")\n#二进制,逢二进一\nbase_2 = str_to_int("10",base = 2)\nprint(base_10, base_2)', 'base_10': 10, 'base_2': 2, '_i5': '#位置参数与关键字参数\n#定义求余函数\ndef calculate_remainder(m, n):\n return m%n\n#位置参数\nprint(calculate_remainder(10,3))\n#关键字参数\nprint(calculate_remainder(n = 3, m = 10))', 'calculate_remainder': <function calculate_remainder at 0x000001FB24682C00>, '_i6': '# 可变长非关键字参数\nprint(min(1,2,3,5))\nprint(min(5,6,7))', '_i7': 'def func(*args):\n print("*args value:", args)\n print("*args type :", type(args))\n print("*args拆包后:", *args)\nfunc(1,2,3)', 'func': <function func at 0x000001FB24683380>, '_i8': 'def count_max_min(x, y, *args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', 'count_max_min': <function count_max_min at 0x000001FB24683060>, 'listv': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], '_i9': '# 定义一个函数,分别求给定数据的最大值与最小值\ndef count_max_min(x, y, *args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n print(max_val, min_val)\n\nlistv = list(range(10))\n#调用时拆包;\n#调用时打包为元组;\ncount_max_min(1,2,*listv)', '_i10': '# 可变长关键字参数\n#定义方式:\ndef func(**kwargs):\n print("**kwargs value:", kwargs)\n print("**kwargs type :", type(kwargs))\n print("*kwargs:", *kwargs)\n#调用方式\nfunc(name="sun", age=10)', '_i11': 'def test(**kwargs):\n func(**kwargs)\n\ndinfo = {"name":"sun", "age":10}\n#调用test时候进行拆包为关键字参数\n#执行中test将其打包成字典\ntest(**dinfo)', 'test': <function test at 0x000001FB24682B60>, 'dinfo': {'name': 'sun', 'age': 10}, '_i12': '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))', 'test_func': <function test_func at 0x000001FB24682AC0>, 'glist': [1], 'v1': [1], 'v2': [2, 3], 'v3': [2, 3], '_i13': '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\n\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '_i14': '#函数参数陷阱\n#listv默认值列表\ndef test_func(value, listv = []):\n print(id(listv))\n listv.append(value)\n return listv\nglist = []\nv1 = test_func(1, glist)\nv2 = test_func(2)\nv3 = test_func(3)\n\nprint(v1, id(v1))\nprint(v2, id(v2))\nprint(v3, id(v3))', '_i15': '#默认返回值\ndef func():\n pass\nres = func()\nprint(res, type(res))', '_i16': '# return返回单个结果\ndef foo(x, y):\n return x+y\n\nres = foo(10, 20)\nprint(res)', 'foo': <function foo at 0x000001FB24682A20>, '_i17': '# 返回多个对象\ndef count_max_min(x,y,*args):\n max_val = max(x, y, *args)\n min_val = min(x, y, *args)\n return max_val, min_val\n\nres = count_max_min(10, 20, 2,3,4,5)\nprint(res)\nmax_value, min_value = count_max_min(10, 20, 2,3,4,5)\nprint(max_value, min_value)', 'max_value': 20, 'min_value': 2, '_i18': '### 1.2 作用域\n作用域:变量在程序中的可应用范围\n\n引入作用域操作:定义函数,类\n\n#### 1.2.1 LEGB原则\n1. L:Local——(函数内部)局部作用域\n\n2. E:Enclose——(嵌套函数的外层函数内部)嵌套作用域(闭包)\n\n3. G:Global——(模块全局)全局作用域\n\n4. B:Buildin ——(内建)内建作用域', '_i19': 'x = 10\ndef func():\nx = 1\nprint("in func x:", x)\nfunc()\nprint("out func x:", x)', '_i20': 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\nfunc()\nprint("out func x:", x)', 'x': 10000, '_i21': 'x = 10\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_i22': 'x = 100000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())', '_i23': 'x = 10000\ndef func():\n x = 1\n print("in func x:", x)\n print("locals:", locals())\nfunc()\nprint("out func x:", x)\nprint("globals:", globals())'}
#作用域陷阱
x = 10
def func():print(x)x = 20
func()
---------------------------------------------------------------------------UnboundLocalError Traceback (most recent call last)Cell In[24], line 64 print(x)5 x = 20
----> 6 func()Cell In[24], line 4, in func()3 def func():
----> 4 print(x)5 x = 20UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
# global关键字
# 如何在局部变量中使用全局变量?x = 10
y = 10
def g_test():global xx = 20y = 30
g_test()
print("x=%d,y=%d"%(x, y))
x=20,y=10
2 匿名函数
2.1 一个需求
需求:判断一个数字是否是奇数,如果是奇数返回True,否则返回False
def is_odd(x):return x%2 == 1x = 10
print(f"{x} is odd:{is_odd(x)}")
x = 11
print(f"{x} is odd:{is_odd(x)}")
10 is odd:False
11 is odd:True
问题:这种简单的函效,能不能通过一条语句实现?
2.2 lambda
lambda;表示定义匿名函数,基本语法:
#定义语法func = lambda:pass#调用方法func()
说明:
- lambda为关键字,在其他语言,例如:java中,也存在这种语法;
- 匿名函数没有名称,返回值为函数对象;
- 匿名函数中的表达式只能由一条语句;
- 匿名函数调用后返回值为表达式结果;
- 匿名函数不要太复杂,要考虑后期维护;
# 无参匿名函数
import time
get_ts = lambda:time.time()
get_ts()
1695371074.136779
# 带参数的匿名函数
'''
1. 计算两个数的和;
2. 给定一个成绩,判断是否及格(判断标准:大于等于60);
'''
x = 60
y = 50
my_add = lambda m, n: m + n
print(f"{x}+{y}= {my_add(x,y)}")
is_pass = lambda value:True if value >= 60 else False
print(f"{x} is pass:{is_pass(x)}")
print(f"{y} is pass:{is_pass(y)}")
60+50= 110
60 is pass:True
50 is pass:False
# 可变长参数匿名函数
my_sum = lambda x, y, *args: x + y + sum(args)
res = my_sum(1,2,3,4,5,6)
print(res)
21
2.3 匿名函数应用
2.3.1 列表排序
需求:给定数字列表.按照规则排序:每个元素与5的差的绝对值,从小到大排序;
nums = [-3, 2, 1,9,10]
nums.sort(key = lambda value:abs(5-value), reverse=False)
print(nums)
[2, 1, 9, 10, -3]
2.3.2 字典列表排序
给定一组用户信息,数据格式如下:
user_info = [{'name':'sun', 'age':10},{'name':'li', 'age':13},{'name':'zhao', 'age':12}]
需求:按照用户年龄从小到大排序
user_info = [{'name':'sun', 'age':15},{'name':'li', 'age':12},{'name':'zhao', 'age':13}]
user_info.sort(key=lambda item:item.get('age'))
user_info
[{'name': 'li', 'age': 12},{'name': 'zhao', 'age': 13},{'name': 'sun', 'age': 15}]
3 函数式编程
3.1 map函数
map(func, *iterables):对迭代对象每个元素处理,返回map对象
需求:
-
将字符串列表:
['1', '2', '3']
转成:[1,2,3]
-
给定三个学生语文与数学成绩,且一一对应
:[90,80,40
],[88, 92, 77,88
],计算每个学生的总成绩; -
某次消费记
录:bill = ['Apple 20', 'Pear 5', 'Banana 10
’] ,计算消费金额,结果为:35;
# 将字符串列表:['1', '2', '3']转成:[1,2,3]
l = ['1', '2', '3']
[int(val) for val in l]
[1, 2, 3]
r = map(int, l)
list(r)
[1, 2, 3]
# 给定三个学生语文与数学成绩,且一一对应:[90,80,40],[88, 92, 77,88],计算每个学生的总成绩;
math = [90,80,40]
chinese = [88, 92, 77,88]
res = map(lambda x, y, *args:x+y+sum(args), math, chinese)
list(res)
[178, 172, 117]
# 某次消费记录:bill = ['Apple 20', 'Pear 5', 'Banana 10'] ,计算消费金额,结果为:35;
bill = ['Apple 20', 'Pear 5', 'Banana 10']
res = sum(map(lambda val:int(val.split()[-1]), bill))
res
35
# 思考问题: 当调用map函数计算成绩时,是否发生了计算?def my_sum(x, y):print(f"{x}+{y}={x+y}")return x + y
math = [90,80,40]
chinese = [88, 92, 77,88]
#查看执行map结果
res = map(my_sum, math, chinese)
print(res)
res = list(res)
print(res)
<map object at 0x000001FB247F3E20>
90+88=178
80+92=172
40+77=117
[178, 172, 117]
3.2 reduce函数
reduce函数:
from functools import reducereduce(function, sequence[, initial])
说明:
-
function函数参数为2个;
-
reduce调用过程:依次从sequence中取一个元素,和上一次function的结果做参数,再次调用function;
-
第一次调用function时,如果设置initial,function参数为:sequence的第一个元素和initial;
-
第一次调用function时,没有设置initial, function参数为:sequence中的前两个元素;
# 计算1~10的累加和;
from functools import reduce
res = reduce( lambda x, y: x+y, range(1, 11) )
print(f"sum res:", res)
#计算1~10阶乘
res = reduce( lambda x, y: x*y, range(1, 11) )
print(f"factorial res:", res)
sum res: 55
factorial res: 3628800
# 给定一组消费数据,计算累积销售额;
order_list = [{"数量":2, "单价":15},{"数量":1, "单价":10},{"数量":7, "单价":12},{"数量":4, "单价":13},]
def count_amount(value, order):amount = order.get("数量") * order.get("单价")return value + amountreduce(count_amount, order_list, 0)
176
3.3 fliter函数
filter函数用于根据条件过滤数据;
filter(function or None, iterable)
-
filter作用:使用function对iterable每个元素进行处理, 将返回值为真的保留,返回filter迭代器;
-
function为指定函数:处理iterable每个元素;
-
function为None:根据iterable中的元素进行判断;
# 1. l = [1,2,3,4,5,6],过滤列表中的偶数;
l = [1,2,3,4,5,6]
res = filter(lambda val:val%2==0, l)
list(res)
[2, 4, 6]
# 2. report = [[90,80],[55,70],[50,45]],过滤成绩,平均分及格;
report = [[90,80],[55,70],[50,45]]
res = filter(lambda item:sum(item)/len(item) >=60, report)
list(res)
[[90, 80], [55, 70]]
4 递归函数
4.1 递归基本原理
递归函数:函数在内部调用自身;
递归函数特性:
-
函数内部,自己调用自己;
-
有一个明确的结束条件;
-
每次进入更深一层递归时,问题规模相比上次递归都应有所减少;
-
python中使用递归考虑
递归优缺点:
-
优点:逻辑简单清晰,
-
缺点:过深的调用会导致栈溢出;栈溢出
deep = 1
def func():global deepdeep += 1print("call func")func()
func()
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
call func
...
call func
call func
call func
call funcRecursionError: maximum recursion depth exceeded while calling a Python object
栈溢出,递归报错!
deep
2973
4.2 阶乘实现
需求:计算N以内阶乘,1*2*3*....n
# 使用while循环
v = 1
i = 1
while i <=5:v *= ii+=1
print(v)
120
#递归实现
def recursion(num):print("num :", num)if num == 1:return numreturn num * recursion(num - 1)
recursion(5)
num : 5
num : 4
num : 3
num : 2
num : 1120
4.3 斐波那契数列
斐波那契数列:即著名的兔子数列:1、1、2、3、5、8、13、21、34、……
#输入n,计算对应的斐波那契数;
def fibo(n):if n <= 2:return 1else:return fibo(n-1) + fibo(n-2)for n in range(1, 10):print(fibo(n), end=" ")
1 1 2 3 5 8 13 21 34
4.4 遍历多维列表
需求:遍历多维列表中的每个元素,注意:列表中子元素为:列表,单个字符,数字; 问题:
data = [1,2,3,['a', 'b', 'c',['d','e','f']],[4,5,6,[7,8,9]]]
def sort_list(items):for item in items:if isinstance(item, list):sort_list(item)else:print(item, end=" ")
sort_list(data)
1 2 3 a b c d e f 4 5 6 7 8 9
5 闭包
5.1 基本概念
内部函数中,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)
# inner_fun是个闭包
def out_func(x):m = 10def inner_func(n):return n * m * xreturn inner_funcres = out_func(3)
res(2)
60
5.2 闭包理解
-
函数内部定义函数;
-
内部函数引用外部变量;
-
函数返回值为函数;
def foo():m = 10def bar(n):return n * mprint("id(bar):", id(bar))return bar
res = foo()
print(id(res))
print(res)
res(2)
id(bar): 2178159224096
2178159224096
<function foo.<locals>.bar at 0x000001FB24682520>20
在这个函数中,foo是外部函数,bar是内部函数,m是外部函数的局部变量,n是内部函数的参数。bar可以访问m和n,并返回它们的乘积。foo的返回值是bar的引用,也就是一个函数对象。当我们调用foo的时候,它会打印出bar的内存地址,并返回bar。当我们用foo的返回值去调用bar的时候,它会使用foo中的m和bar中的n进行计算,并返回结果。
func = foo()
func(2)
id(bar): 217817983756820
5.3 闭包使用场景
5.3.1 n次幂计算
需求:定义一组函数,计算指定数值N次幂
def make_pow2(n):return pow(n, 2)
def make_pow10(n):return pow(n, 10)
print("make_pow2(2)=",make_pow2(2))
print("make_pow10(2)=",make_pow10(2))
make_pow2(2)= 4
make_pow10(2)= 1024
# 传入参数可以为数字字符串,如何处理?
def make_pow2(n):return pow(int(n), 2)
def make_pow10(n):return pow(int(n), 10)
5.3.2 闭包使用场景
-
封装,代码复用;
-
装饰器;
# 可变长参数
def logfunc(level='info'):def logmsg(msg, *args, **kwargs):print(f'{level}--> : {msg}, {args},{kwargs}')return logmsgdebug_func = logfunc('debug')
info_func = logfunc('info')
error_func = logfunc('error')debug_func("test", 1,2,3, y=10)
info_func("info")
error_func("error")
debug--> : test, (1, 2, 3),{'y': 10}
info--> : info, (),{}
error--> : error, (),{}
可变长参数是指在调用函数时,传入的参数个数可以不固定。
Python支持两种可变长参数,分别是*args
和**kwargs
,它们分别用来接收位置参数和关键字参数。
5.3.3 __closure__属性
__closure__是一个Python的属性,它用来表示一个函数对象是否是一个闭包函数。
__closure__属性的值是一个元组,它包含了所有被内部函数引用的外部函数的变量,这些变量被称为自由变量。每个自由变量都是一个cell类型的对象,它有一个cell_contents属性,用来存储变量的值。
# __closure__属性
def logfunc(level='info'):def logmsg(msg, *args, **kwargs):print(f'{level}--> : {msg}')return logmsginfo_func = logfunc('info')
print("info地址 :0x%016X"%id("info"))
info地址 :0x00007FFDEA00D400
info_func.__closure__
(<cell at 0x000001FADA79BA00: str object at 0x00007FFDEA00D400>,)
attr = info_func.__closure__
print("info地址 :0x%016X"%id("info"))
print("闭包closure:",type(attr), attr)
print("外部变量值 :",attr[0].cell_contents)
info地址 :0x00007FFDEA00D400
闭包closure: <class 'tuple'> (<cell at 0x000001FADA79BA00: str object at 0x00007FFDEA00D400>,)
外部变量值 : info
6 装饰器
装饰器:对函数进行处理,并返回新的函数
6.1 再看闭包
需求:定义一系列函数,对函数进行检验,前两个参数必须为整数;
def make_pow(x, y):print("call make_pow")if isinstance(x, int) and isinstance(y, int):return x ** y
def make_sum(x, y):print("call make_sum")if isinstance(x, int) and isinstance(y, int):return x + y
def make_mul(x, y):print("call make_mul")if isinstance(x, int) and isinstance(y, int):return x * y
问题:三个函数中检查参数重复,如果还要对其他参数进行检验,如何操作?
def deco_func(f):print("call deco_func")def inner(x, y, *args):print("call here inner")if isinstance(x, int) and isinstance(y, int):return f(x, y, *args)return innerdef make_pow(x, y, *args):print("call make_pow")return x ** ymake_new_pow = deco_func(make_pow)
call deco_func
make_new_pow(2,3,7)
call here inner
call make_pow8
6.2 使用装饰器
装饰器基本语法:
def deco_func(f):def inner(): return f( return inner@deco_funcdef fo ():pas注意:
1. deco_func为装饰器函数,2. foo被装饰函数,3. 当运行此代码,deco_func被调用,过程:foo = deco_func(foo),4. 结果:foo函数成为inner函数外部变量,foo指向inner函数s
#装饰器函数
def deco_func(f):print("call deco_func")def inner(x, y, *args):print("call here inner")if isinstance(x, int) and isinstance(y, int):return f(x, y, *args)return inner#被装饰函数
#@deco_func为装饰器语法糖:含义为make_pow=deco_func(make_pow)
@deco_func
def make_pow(x, y, *args):print("call make_pow")return x ** y
call deco_func
make_pow(2,3)
call here inner
call make_pow8
问题:如何在输出信息中添加:info, debug, error;
解决方式:将deco_func修改为内部变量,在外添加level_func
def level_func(level):def deco_func(f):def inner(msg):'''inner lever'''msg = level + " msg:"+msgf(msg)return innerreturn deco_func
#调用过程
#1:调用level_func,返回deco_func,
#2:@deco_func对log_info进行装饰,返回inner
@level_func("info")
def log_info(msg):'''info level'''print(msg)@level_func("error")
def log_error(msg):'''error level'''print(msg)log_info("this is test")
log_error("this is test")
info msg:this is test
error msg:this is test
log_error?
[1;31mSignature:[0m [0mlog_error[0m[1;33m([0m[0mmsg[0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m
[1;31mDocstring:[0m inner lever
[1;31mFile:[0m c:\users\26822\appdata\local\temp\ipykernel_17220\3799119143.py
[1;31mType:[0m function
6.3 wraps
装饰器使用问题:某些场景下,我们希望使用装饰器,但是,不希望改变函数名及说明,例如:
from functools import wraps
def deco_func(f):#使用wraps装饰f@wraps(f)def bar():'this bar func'f()return bar@deco_func
def test():'this is test func, do nothing'passtest?
[1;31mSignature:[0m [0mtest[0m[1;33m([0m[1;33m)[0m[1;33m[0m[1;33m[0m[0m
[1;31mDocstring:[0m this is test func, do nothing
[1;31mFile:[0m c:\users\26822\appdata\local\temp\ipykernel_17220\1862026155.py
[1;31mType:[0m function
7 yield与生成函数
主要内容
-
yield;
-
生成器函数应用;
-
基于yield实现生产者与消费
7.1 带yeild关键字函数者;
def func():print("--> step 1")yield "hello"print("--> step 2")yield "world"print("--> step 3")
gen = func()
gen
<generator object func at 0x000001FADA703AC0>
next(gen)
--> step 1'hello'
next(gen)
--> step 2'world'
next(gen)
--> step 3---------------------------------------------------------------------------StopIteration Traceback (most recent call last)Cell In[29], line 1
----> 1 next(gen)StopIteration:
调用说明:
- func被调用,并不会执行;
- func被调用后返回生成器;
- 可以使用next函数或者for对生成器操作;
yield的调用过程:
- 第一次调用next(gen)执行后,遇到yield关键字,返回其对应的对象,并保存现场;
- 再次调用next(gen),从yield的下一条语句继续执行;
- 重复1~2,如果执行完成,触发StopIteration异常;
7.2 yield使用场景
需求:
-
生成随机数池,可以无限取值,范围:[1, 9999];
-
使用yield完成斐波那契数列;
# 随机数池
import random
def random_pool(min_val, max_val):while True:yield random.randint(min_val, max_val)
random_gen = random_pool(1, 9999)
next(random_gen)
6363
#斐波那契数列
def fibo(n):a,b = 0, 1i = 1while i < n:i += 1yield ba, b = b, a+b
gen_fibo = fibo(10)
for val in gen_fibo:print(val)
1
1
2
3
5
8
13
21
34
7.3 send方法
生成器函数可以传参并接受参数
-
生成器对象调用send方法传参;
-
生成器函数 value = yield obj接受参数
需求:定义生成器函数,将字符串数字转成整数,若转化值为"q",退出;;
def custom():value = yield ''while value != 'q':value = yield int(value)*10
gen = custom()
next(gen)
''
gen.send('20')
200
gen.send('q')
---------------------------------------------------------------------------StopIteration Traceback (most recent call last)Cell In[40], line 1
----> 1 gen.send('q')StopIteration:
调用过程:
-
使用next方法,启动生成器,生成器返回"",保留现场,等待下一次调用;
-
调用生成器send方法,传入参数,value接受参数,执行到yield返回并保存现场;
-
重复1~2过程,如果遇到"q",退出;