-
闭包
-
装饰器
-
迭代器
-
生成器
闭包
保证数据安全
全局变量可随意修改,数据不安全
如果放到一个函数中,数据安全了,但是无法引用
def demo(): name = "张三" print(name)# 报错
如何既可以引用函数里面的变量,又可以保证数据的安全性?这个时候就会用到闭包
闭包 结构
内层函数对外层函数的局部变量的使用,内层函数被称为闭包函数
闭指的是:该函数的内部函数
包指的是:内部函数在外部被引用
构成条件
1、函数嵌套
2、外部函数返回内部函数名
3、内部函数使用外部函数的变量
def a():
print("外部函数")
def b():
print("内部函数")
return b
res = a()
res()
实现
外层函数内的变量被称为自由变量,这个自由变量和内层函数形成一种绑定关系,自由变量不会和全局变量产生冲突
def external():
name = "外层函数"
def inside():
print("我是内部函数")
return name
return inside
res = external()
r1 = res()
print(r1)
装饰器
装饰器是 Python 的一个重要部分。简单地说:他们是不改变函数功能的基础上,给函数增加一些功能。他们有助于让我们的代码更简短,也更有范儿。
1、函数可以作为参数进行传递
def func(des):
return des()
def func1():
print("我是流的换")
func(func1)
装饰器的本质是一个闭包
装饰器的参数
返回值
def func1(a):
def func2(*args, **kwargs):
print("外挂开启")
a(*args, **kwargs)
print("外挂关闭")
return "感谢使用"
return func2
@func1
def lol_game(username, password, name):
print(username + "\t" + password + "\t" + name + "召唤师:" + "欢迎来到英雄联盟!")
@func1
def wzly_game(username, password):
print(username + "\t" + password + "\t" + "玩家使用李兴:" + "我就是太阳!")
str1 = lol_game("1234567", "4567890", "哇哎")
print(str1)
str2 = wzly_game('1231230', "45654654")
print(str2)
迭代器
迭代器是一种对象,该对象包含值的可计数数字。
迭代器是可迭代的对象,这意味着您可以遍历所有值。
从技术上讲,在 Python 中,迭代器是实现迭代器协议的对象,它包含方法 iter() 和 next()。
迭代器与可迭代对象
列表、元组、字典和集合都是可迭代的对象。它们是可迭代的容器,您可以从中获取迭代器(Iterator)。
所有这些对象都有用于获取迭代器的 iter() 方法:
str1 = iter("你好呀") print(str1) # <str_iterator object at 0x0000018D4EF0BFA0> ------------------------------------------------------------- str1 = "你好呀".__iter__() print(str1) # <str_iterator object at 0x0000018D4EF0BFA0>
从迭代器中拿到数据
while 模拟for循环
str1 = "你好,刘德华。".__iter__()
str2 = iter("我叫胡歌。")
str3 = "我听过你的节目。".__iter__()
print(str1)
print(str2)
print(str3)
for i in str1:
print(i,end="")
print()
while True:
try:
print(str2.__next__(),end="")
except StopIteration:
break
print()
print(str3.__next__())
print(str3.__next__())
print(str3.__next__())
生成器
生成器的本质就是迭代器
创建生成器的方案
生成器函数中有一个关键字 yield
生成器函数执行的时候,并不会执行函数,得到的是生成器
def func():
print("123456")
yield "everyone,Hello!!"
res = func()
print(type(res))
print(res.__next__())
<class 'generator'>
123456
everyone,Hello!!
只要函数中出现了yield,那他就是一个生成器函数
可以返回数据
func1()函数可以分段执行函数的内容,通过next,执行到下一个yield的位置
和 return 相比,yield 除了可以返回相应的值,还有一个更重要的功能,即每当程序执行完该语句时,程序就会暂停执行。不仅如此,即便调用生成器函数,Python 解释器也不会执行函数中的代码,它只会返回一个生成器(对象)
def func():
li = []
for i in range(50):
li.append(f"我的第{i}个理由")
yield li
def func1():
print("1111111111111")
yield "2222222222"
print("3333333333333")
yield "444444444444"
list1 = func()
print(list1)
print(type(list1))
print(list1.__next__())
res = func1()
print(res.__next__())
print(res.__next__())
# 打印的内容
# <generator object func at 0x0000020D59494350>
#<class 'generator'>
#['我的第0个理由', '我的第1个理由', '我的第2个理由', '我的第3个理由', '我的第4个理由', '我的3第5个理由', '我的第6个理由', '我的第7个理由', '我的第8个理由', '我的第9个理由', '我的第10个理由', '我的第11个理由', '我的第12个理由', '我的第13个理由', '我的第14个理由', '我的第15个理由', '我的第16个理由', '我的第17个理由', '我的第18个理由', '我的第19个理由', '我的第20个理由', '我的第21个理由', '我的第22个理由', '我的第23个理由', '我的第24个理由', '我的第25个理由', '我的第26个理由', '我的第27个理由', '我的第28个理由', '我的第29个理由', '我的第30个理由', '我的第31个理由', '我的第32个理由', '我的第33个理由', '我的第34个理由', '我的第35个理由', '我的第36个理由', '我的第37个理由', '我的第38个理由', '我的第39个理由', '我的第40个理由', '我的第41个理由', '我的第42个理由', '我的第43个理由', '我的第44个理由', '我的第45个理由', '我的第46个理由', '我的第47个理由', '我的第48个理由', '我的第49个理由']
1111111111111
2222222222
3333333333333
444444444444