目录
1.概述
"""
函数的嵌套
变量的作用域
闭包
装饰器
迭代器
生成器
推导式
匿名函数
python的内置函数 sorted,filter,map
"""
2.作用域
作用域:变量的访问权限
a = 10 #全局变量
print(a) # 10
def fun():
b = 20 #局部变量,局部作用域
print(a)
fun() # 10
3.函数的嵌套
""" 函数可以嵌套函数 综上: 1.函数可以作为返回值进行返回 2.函数可以作为参数进行互相传递 函数名实际上就是一个变量名,都表示一个内存地址 """
def fun1():
b = 20
def fun2(): #函数的嵌套,局部变量
pass
print(b)
fun2()
print(fun1()) # 20
# None
练习题:
def func1():
print(123)
def fun2():
print(456)
def fun3():
print(789)
print(1)
fun3()
print(2)
print(3)
fun2()
print(4)
func1()
#结果:
123
3
456
1
789
2
4
# 函数可以作为返回值进行返回
def fun():
def inner():
print(123)
print(inner)
return inner #返回的是一个函数,此时我们把一个函数当成一个变量进行返回的
b1 = fun() # b1是func的内部inner
print(b1)
b1()
# 结果:
<function fun.<locals>.inner at 0x0000018DA3365790>
<function fun.<locals>.inner at 0x0000018DA3365790>
123
# 函数可以作为参数进行互相传递
def an():
print(123)
an() # 123
bn = an
bn() # 123
# # 代理模式
def func(an): # 此时an收到的是一个函数
print(an) # 执行这个函数
def target():
print("我是target")
c = 456
func(target) # 实参可以是函数
#结果:<function target at 0x00000129A9204790>
4.两个关键字
global a # 把外面的全局变量引入到局部
nonlocal #向外找一层,看看有没有该变量,如果有就引入
a = 10
def func():
# 此时我就想在函数内部修改全局变量a
global a # 把外面的全局变量引入到局部
a = 20 # 创建一个局部变量,并没有去改变全局变量中的a
func()
print(a) # 结果:20
def func():
a = 10
def func2():
nonlocal a #向外找一层,看看有没有该变量,如果有就引入,如果没有,继续向外一层,直到全局(不包括)
a = 20
func2()
print(a)
func() #结果:20
5.闭包
闭包:本质:内层函数对外层函数的局部变量的使用,此时内层函数被称为闭包函数 1.可以让一个变量常驻与内存 2. 可以避免全局变量被更改
def func():
a = 10
def inner():
nonlocal a
a = a + 1
return a
return inner
ret = func()
a = 20
r1 = ret()
print(r1) # 11
r2 = ret()
print(r2)# 12
6.装饰器
"""
内容回顾:
1.函数可以作为参数进行传递
2.函数可以作为返回值进行返回
3.函数名称可以当成变量一样进行复制操作
装饰器: -> 要求记住最后的结论
装饰器就是一个特殊的闭包
作用:
再不改变原有函数调用的情况下,给函数增加新的功能
直白:可以在函数前后添加新功能,但是不改变原来的代码。
锥形:
def wrapper(fn):
def inner(*args,**kwargs):
函数执行之前。。。。
ret = fn(*args,**kwargs)
函数执行之后。。。。
return ret
return inner
@wrapper
def target():
pass
target() # => inner()
一个函数可以被多个装饰器装饰
"""
6.1 内容回顾
1.函数可以作为参数进行传递
def func():
print("我是函数")
def ggg(fn):
fn()
ggg(func) #结果:我是函数
def func():
def inner():
print('123')
return inner
ret = func()
ret() #结果:123
6.2 简单举例
1.无传参
def guanjia(game):
def inner():
print("开启外挂")
game()
print("关闭外挂")
return inner
@guanjia
def play_lol():
print("德玛西亚")
play_lol()
#结果:
开启外挂
德玛西亚
关闭外挂
2.有传参
def guanjia(game):
def inner(username,password):
print("开启外挂")
game(username,password)
print("关闭外挂")
return inner
@guanjia
def play_lol(username,password):
print("我要开始玩lol了",username,password)
print("德玛西亚")
play_lol("hcb2001","123")
结果:
开启外挂
我要开始玩lol了 hcb2001 123
德玛西亚
关闭外挂
3.*args,**kwargs
def guanjia(game):
# * ** 表示接收所有参数,打包成元组和字典
def inner(*args,**kwargs): # arge肯定是一个元组 , kwargs肯定是一个列表
print("开启外挂")
# *,** 表示把args元组和kwargs字典打散 位置参数以及关键字参数传递进去
game(*args,**kwargs)
print("关闭外挂")
return inner
#
#
@guanjia
def play_lol(username,password):
print("我要开始玩lol了",username,password)
print("德玛西亚")
#
#
@guanjia
def play_dnf(username,password,hero):
print("我要开始玩dnf了",username,password,hero)
print("德玛西亚")
play_lol("hcb2001","123")
play_dnf("hcb2001","123456","墨白")
#结果:
开启外挂
我要开始玩lol了 hcb2001 123
德玛西亚
关闭外挂
开启外挂
我要开始玩dnf了 hcb2001 123456 墨白
德玛西亚
关闭外挂
4.返回值
def guanjia(game):
# * ** 表示接收所有参数,打包成元组和字典
def inner(*args,**kwargs): # arge肯定是一个元组 , kwargs肯定是一个列表
print("开启外挂")
# *,** 表示把args元组和kwargs字典打散 位置参数以及关键字参数传递进去
ret = game(*args,**kwargs)
print("关闭外挂")
return ret
return inner
@guanjia
def play_lol(username,password):
print("我要开始玩lol了",username,password)
print("德玛西亚")
return "一把刀"
res = play_lol("hcb2001","123")
print(res)
#结果:
开启外挂
我要开始玩lol了 hcb2001 123
德玛西亚
关闭外挂
一把刀
5.一个函数被多个装饰器装饰
def wrapper1(fn): #fn:wrapper2.inner
def inner(*args,**kwargs):
print("这里是wrapper1 进入")
ret = fn(*args,**kwargs)
print("这里是wrapper1 出去")
return ret
return inner
def wrapper2(fn): #fn:target
def inner(*args,**kwargs):
print("这里是wrapper2 进入")
ret = fn(*args,**kwargs)
print("这里是wrapper2 出去")
return ret
return inner
@wrapper1 # target = wrapper1(wrapper2.inner) => target:wrapper1.inner
@wrapper2 # target = wrapper2(target) => target:wrapper2.inner
def target():
print("我是目标")
target()
# 结果:
这里是wrapper1 进入
这里是wrapper2 进入
我是目标
这里是wrapper2 出去
这里是wrapper1 出去
7.迭代器
"""
for 变量 in 可迭代:
pass
iterable: 可迭代的东西
iterator: 迭代器
str, list, tuple, dict, set, open()
可迭代的数据类型都会提供一个叫迭代器的东西. 这个迭代器可以帮我们把数据类型中的所有数据逐一的拿到
获取迭代器的两种方案:
1. iter() 内置函数可以直接拿到迭代器
2. __iter__() 特殊方法
从迭代器中拿到数据:
1. next() 内置函数
2. __next__() 特殊方法
for里面一定是要拿迭代器的. 所以所有不可迭代的东西不能用for循环
for循环里面一定有__next__出现
总结: 迭代器统一了不同数据类型的遍历工作
迭代器本身也是可迭代的
迭代器本身的特性:
1. 只能向前不能反复
2. 特别节省内存
3. 惰性机制
"""
1.iter()
it = iter("你叫什么名字啊")
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it))
print(next(it)) # StopIteration: 迭代已经停止了. 不可以再次从迭代器中拿数据了
结果:
it = "呵呵哒".__iter__()
print(it.__next__())
print(it.__next__())
print(next(it))
# 结果:
呵
呵
哒
s = "你好啊, 我叫赛利亚"
it = s.__iter__()
for mm in it:
print(mm)
#结果:
你
好
啊
,
我
叫
赛
利
亚
Process finished with exit code 0
8.生成器
"""
生成器(generator):
生成器的本质就是迭代器
创建生成器的两种方案:
1. 生成器函数
2. 生成器表达式
生成器函数
生成器函数中有一个关键字yield
生成器函数执行的时候, 并不会执行函数, 得到的是生成器.
yield: 只要函数中出现了yield. 它就是一个生成器函数
作用:
1. 可以返回数据
2. 可以分段的执行函数中的内容, 通过__next__()可以执行到下一个yield位置
优势:
用好了, 特别的节省内存
生成器表达式 -> 一次性的
语法: (数据 for循环 if)
"""
生成器函数
def func():
print(123456)
yield 999 # yield也有返回的意思.
ret = func()
# print(ret) # <generator object func at 0x115f2dbd0>
print(ret.__next__()) # yield只有执行到next的时候才会返回数据
print(ret.__next__()) # StopIteration
结果:
def func():
print(123)
yield 666
print(456)
yield 999
ret = func()
print(ret.__next__())
print(ret.__next__())
#结果:
123
666
456
999
def order():
lst = []
for i in range(10000):
lst.append(f"衣服{i}")
if len(lst) == 50:
yield lst
# 下一次拿数据
lst = []
gen = order()
print(gen.__next__())
print(gen.__next__())
结果:
9.推导式
"""
推导式:
简化代码.
语法:
列表推导式: [数据 for循环 if判断]
集合推导式: {数据 for循环 if判断}
字典推导式: {k:v for循环 if判断}
不要把推导式妖魔化.
(数据 for循环 if判断) -> 不是元组推导式, 根本就没有元组推导式. 这玩意叫生成器表达式
"""
lst = []
for i in range(10):
lst.append(i)
print(lst) #结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
lst = [i for i in range(10)]
print(lst) #结果:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1. 请创建一个列表[1,3,5,7,9]
lst = [i for i in range(1, 10, 2)]
lst = [i for i in range(10) if i % 2 == 1]
print(lst)
# 结果:[1, 3, 5, 7, 9]
2. 生成50件衣服
lst = [f"衣服{i}" for i in range(50)]
print(lst)
#结果:['衣服0', '衣服1', '衣服2', '衣服3', '衣服4', '衣服5', '衣服6', '衣服7', '衣服8', '衣服9', '衣服10', 。。。。。]
3. 将如下列表中所有的英文字母修改成大写
lst1 = ["allen", "tony", "kevin", "sylar"]
lst2 = [item.upper() for item in lst1]
print(lst2)
#结果:['ALLEN', 'TONY', 'KEVIN', 'SYLAR']
4. 请将下列的列表修改成字典, 要求 索引做为key, 数据作为value
lst = ['赵本山', "潘长江", "高达", "奥特曼"]
dic = {i: lst[i] for i in range(len(lst))}
print(dic) #结果:{0: '赵本山', 1: '潘长江', 2: '高达', 3: '奥特曼'}
10.匿名函数
"""
匿名函数:
lambda表达式
语法:
变量 = lambda 参数,参数2,参数3....: 返回值
"""
fn = lambda a, b: a + b
ret = fn(12, 13)
print(ret)
# 结果:25
11.内置函数
"""
zip: 可以把多个可迭代内容进行合并
sorted: 排序
filter: 筛选
map: 映射
"""
zip: 可以把多个可迭代内容进行合并
普通:
lst1 = ["赵本山", "范伟", '苏有朋']
lst2 = [40, 38, 42]
lst3 = ["卖拐", "耳朵大有福", "情深深雨蒙蒙"]
result = []
for i in range(len(lst1)):
first = lst1[i]
second = lst2[i]
third = lst3[i]
result.append((first, second, third))
print(result)
用zip:
lst1 = ["赵本山", "范伟", '苏有朋']
lst2 = [40, 38, 42]
lst3 = ["卖拐", "耳朵大有福", "情深深雨蒙蒙"]
result = zip(lst1, lst2, lst3)
for item in result:
print(item)
# 结果:
('赵本山', 40, '卖拐')
('范伟', 38, '耳朵大有福')
('苏有朋', 42, '情深深雨蒙蒙')
sorted: 排序
lst = [16,22,68,1,147,256,49]
s = sorted(lst, reverse=True) # reverse翻转
print(s)
#结果:[256, 147, 68, 49, 22, 16, 1]
# # 1 3 2 4 123132
lst = ["秋", "张二嘎", "比克", "卡卡罗特", "超级宇宙无敌大帅B"]
# def func(item): # item对应的就是列表中的每一项数据
# return len(item)
s = sorted(lst, key=lambda x: len(x))
print(s)
#结果:['秋', '比克', '张二嘎', '卡卡罗特', '超级宇宙无敌大帅B']
练习:
lst = [
{"id": 1, "name": "周润发", "age": 18, "salary": 5200},
{"id": 2, "name": "周星驰", "age": 28, "salary": 511100},
{"id": 3, "name": "周海媚", "age": 78, "salary": 561230},
{"id": 4, "name": "周伯通", "age": 12, "salary": 532100},
{"id": 5, "name": "周大兴", "age": 35, "salary": 53210},
{"id": 6, "name": "周周有辣", "age": 47, "salary": 520},
{"id": 7, "name": "周扒皮", "age": 8, "salary": 12},
]
# 1.根据每个人的年龄排序
s = sorted(lst, key=lambda d: d['age'])
print(s)
#
# # 2.根据工资进行排序. 从大到小
s = sorted(lst, key=lambda d: d['salary'], reverse=True)
print(s)
结果:
filter: 筛选
lst = ["张无忌", "张三丰", "张翠山", "灭绝小师太", "小狐仙"]
f = filter(lambda x: x.startswith("张"), lst)
print(list(f))
#结果:['张无忌', '张三丰', '张翠山']
map: 映射
lst = [1,2,3,4,5,6,7,8,9]
result = [item * item for item in lst]
print(result)
# 结果:[1, 4, 9, 16, 25, 36, 49, 64, 81]
r = map(lambda x: x * x, lst)
print(list(r))
#结果:[1, 4, 9, 16, 25, 36, 49, 64, 81]