三器一闭
1、判断是否可迭代
from collections.abc import Iterable # 可迭代对象
print(isinstance([], Iterable)) # 空列表
print(isinstance({}, Iterable)) # 字典
print(isinstance((1,), Iterable)) # 元组
print(isinstance(set(), Iterable)) # 集合
print(isinstance('100', Iterable)) # 字符串
print(isinstance(100, Iterable)) # 数值(整型 浮点型)
print(isinstance(range(1, 10), Iterable)) # range对象
# True
# True
# True
# True
# True
# False
# True
2、使用迭代器获取数据
from collections.abc import Iterator, Iterable
nums = [1, 2, 3]
# for i in nums:
# print(i)
print(isinstance(nums, Iterable)) # 可迭代 True
print(isinstance(nums, Iterator)) # 不是一个迭代器 False
nums = iter(nums) # 创建迭代器
print(isinstance(nums, Iterator)) # 是一个迭代器 True
"""正常情况下 如果说想要去迭代器中取数据 使用next()"""
"""try except 进行异常的捕获 StopIteration"""
# print(next(nums)) # 1
# print(next(nums)) # 2
# print(next(nums)) # 3
# print(next(nums)) # 报错 StopIteration
for i in nums: # for循环自带next()方法
print(i)
3、自定义迭代器
import time
from collections.abc import Iterator, Iterable
class Mynumber:
def __iter__(self):
# 实例属性
self.a = 1
print(self, 'self')
return self # 表示实例对象本身是自己的迭代器对象
def __next__(self):
self.a += 1 # 自增1
return self.a
myclass = Mynumber() # 创建对象
# print(isinstance(myclass, Iterable)) # True
# print(isinstance(myclass, Iterator)) # True
myiter = iter(myclass) # 自动调用__iter__方法
# print(isinstance(myiter, Iterator)) # True
"""实现了一个0到正无穷大的一个方法"""
for i in myiter:
# time.sleep(0.1)
# print(i)
if i == 1000000:
print(i) # 1000000
break
# for i in range(1, 20):
# print(next(myiter))
"""
迭代器一定是可迭代对象
可迭代对象不一定是迭代器
1、凡是可作用于for循环的对象都是Iterable 类型;
2、凡是可作用于 next() 函数的对象都是Iterator 类型;
3、集合数据类型如list 、dict、str等是 Iterable但不是Iterator,
不过可以通过 iter()函数获得一个Iterator对象。
"""
4、生成器
"""
1. 定义一个以yield关键字标识返回值的函数;
2. 调用刚刚创建的函数,即可创建一个生成器。
"""
def intNum():
print('开始执行', end="")
for i in range(5):
yield i # return直接停止 yield暂停
print('继续执行', end="")
num = intNum()
# print(num) # 生成器 <generator object intNum at 0x000001D1E25F0970>
# print(num.__next__()) # 开始执行0
# print(num.__next__()) # 开始执行1
# print(num.__next__()) # 开始执行2
# print(num.__next__()) # 开始执行3
# print(next(num)) # 开始执行4 next()和__next__()都可以
"""由于会yield会暂停,所以继续执行这句话不会打印"""
# print(num.__next__()) # StopIteration 超出了长度范围
"""使用for循环可以打印"""
for i in num:
print(i)
# 开始执行0
# 继续执行1
# 继续执行2
# 继续执行3
# 继续执行4
# 继续执行
5、闭包
def outer(x): # 外
def inner(y): # 内
return x + y
return inner
print(outer(6)(5)) # inner(5) 并将 x = 6 携带进去,打印结果为 11
"""
如代码所示,在outer函数内,又定义了一个inner函数,
并且inner函数又引用了外部函数outer的变量x,这就是一个闭包了。
在输出时,outer(6)(5),第一个括号传进去的值返回inner函数,
其实就是返回6 + y,所以再传第二个参数进去,就可以得到返回值,6 + 5。
"""
6、装饰器
"""函数改进过程:在打印 你好,装饰器!之前打印当前时间"""
# def hello():
# print("你好,装饰器!")
#
#
# hello()
import datetime
# 1、直接打印
# def hello():
# print("当前时间:", datetime.datetime.now())
# print("你好,装饰器!")
#
#
# hello()
# 2、高阶函数方式
# def print_time(func):
# print("当前时间:", datetime.datetime.now())
# func()
#
#
# def hello():
# print("你好,装饰器!")
#
#
# print_time(hello)
"""下面使用装饰器完成需求"""
import datetime
# 装饰器函数
def my_decorator(func):
def print_time():
print("当前时间:", datetime.datetime.now())
func()
return print_time
"""
可以将@my_decorator理解为下面两行代码
hello = my_decorator(hello)
hello()
"""
@my_decorator
def hello():
print("你好,装饰器!")
hello()
# 当前时间: 2023-06-09 09:00:53.242777
# 你好,装饰器!