python基础-学习记录day18

100 阅读3分钟

三器一闭

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
# 你好,装饰器!