1. 迭代器
①定义:自定义的类,只要重写了__iter__()和__next__()方法,就可以称为迭代器;惰性加载,用的时候才会获取.
②目的:隐藏底层的逻辑,让用户使用更方便。
2.生成器
①定义:根据程序员制定的规则循环生成数据,当条件不成立时则生成数据结束。数据不是一次性全部生成出来,而是使用一个,再生成一个,可以节约内存。
②创建方式:生成器推导式和yield关键字;
方式一:生成器推导式。语法:
例如:生成器名=(i * 2 for i in range(5));next()获取生成器中的下一个值;for循环遍历生成器中的每一个值;
#1.创建生成器my_generator=(i*2foriinrange(5))print(my_generator)#2.next获取生成器下一个值value=next(my_generator)print(value)#3.遍历生成器forvalueinmy_generator:print(value)#注意:创建生成器时:括号()代表这是一个生成器,不是元组;#括号()里面写的是数据的生成规则,返回一个对象:对象内不是存的数据,而是产生数据的规则方式二:yield 关键字。语法:
只要在def函数里面看到有yield关键字那么就是生成器;
defmy_generater(n):foriinrange(n):print('开始生成...')yieldiprint('完成一次...')if__name__=='__main__':g=my_generater(2)# 获取生成器中下一个值# result = next(g)# print (result)# for遍历生成器,for循环内部自动处理了停止迭代异常,使用起来更加方便foriing:print(i)""" 案例1:演示生成器之 推导式写法 """importsys#system 系统模块# 需求1: 生成1-10之间的整数my_generator=(iforiinrange(1,11))print(my_generator)#运行结果:<generator object <genexpr> at 0x102939820>print(type(my_generator))#运行结果:<class 'generator'># 需求2: 生成1-10之间的偶数my_generator2=(iforiinrange(1,11)ifi%2==0)print(my_generator2)#运行结果:<generator object <genexpr> at 0x102ff1890># 需求3: 如何从生成中获取数据print(next(my_generator2))#运行结果:2print(next(my_generator2))#运行结果:4foriinmy_generator2:print(i)#运行结果:6 8 10# 需求4:验证生成器是可以减少内存占用(数据多的时候明显,因为数据少的时候生成器本身也占内存)list=[iforiinrange(10000000)]generator=(iforiinrange(10000000))print(type(list))#运行结果:<class 'list'>print(type(generator))#运行结果:<class 'generator'># 查看内存空间占用print(f'list的内存占用:{sys.getsizeof(list)}')#运行结果:89095160print(f'generator的内存占用:{sys.getsizeof(generator)}')#运行结果:112""" 案例2:演示生成器之 yield方式 """importsys#system 系统模块# 需求1: 通过yield方式,生成1-10之间的整数# 方式一:推导式写法my_generator=(iforiinrange(1,11))# 方式二:yield方式# 1.定义函数,存储到生成器中并返回defmy_func():# list=[] #创建# for i in range(1,11):# list.append(i) #添加# return list #返回# yield方式效果类似上面的代码# yield此处做了三件事:1.创建生成器对象;2.把值存储到生成器中;3.返回生成器;foriinrange(1,11):yieldi# 2.测试generator=my_func()print(type(generator))#运行结果:<class 'generator'>print(next(generator))#运行结果:1print(next(generator))#运行结果:2print("*"*32)foriingenerator:print(i)#运行结果:3 4 5 6 7 8 9 103. Property属性
定义:负责把一个方法当做属性进行使用,这样做可以简化代码使用;
定义property属性有两种方式:① 装饰器方式;② 类属性方式。
方式一:装饰器方式。语法:@property修饰获取值的方法;@方法名.setter修饰设置值的方法。
classPerson(object):def_init(self):self._age=0#获取属性@propertydefage(self):returnself._age# 修改属性@age.setterdefage(self,new_age):self._age=new_ageif__name__=="__main__":person=Person()print(person.age)person.age=100print(person.age)代码:
""" 案例:演示property属性的用法. property属性介绍: 概述/目的/作用: 把函数当做变量来使用。 实现方式: 方式1:装饰器. 方式2:类属性. property的装饰器用法: @property 修饰获取值的函数 @获取值的函数名.setter 修饰设置值的函数 之后,就可以直接.上述的函数名来当做变量直接用 """#需求:定义学生类,私有属性age,通过property实现简化调用.#1.定义学生类。classStudent:# 1.1 私有属性def__init__(self):self.__age=18# 1.2 提供公共的访问方式@property# def get_age(self):defage(self):returnself.__age# @get_age.setter# def set_age(self, age): # 这里可以做检验但一般不做,除非重要字段才做二次校验@age.setterdefage(self,age):#这里可以做检验但一般不做,除非重要字段才做二次校验self.__age=age# 2.测试if__name__=='__main__':#2.1 创建学生对象student=Student()# 2.2 设置值并获取值# 方式一:传统获取方式:函数方法# student.set_age(10)# print(student.get_age()) # 运行结果:10# 方式二:使用Property属性:把# 即在类的get方法上加上@'property',set方法上加上'@方法名.setter'# 实际开发中直接用age,不用set_age、get_age# student.set_age=10# print(student.get_age) # 运行结果:10student.age=10print(student.age)# 运行结果:10方式二:类属性方式。语法:
即类属性=property(获取值方法,设置值方法);两参数位置不能换,先获取在设置!此时下面的:get_age、set_age不能和方式一那样 两者改名相同,都改为age;
classPerson(object):def_init_(self):self._age=0defget_age(self):#3当获取age属性的时候会执行该方法returnself._agedefset_age(self,new_age):# 当设置age属性的时候会执行该方法self._age=new_age#类属性方式的property属性age=property(get_age,set_age)if__name__=='__main__':person=Person()print(person.age)person.age=100print(person.age)代码:
""" 案例:演示property属性的用法. property属性介绍: 概述/目的/作用: 把函数当做变量来使用。 实现方式: 方式1:装饰器. 方式2:类属性. property的装饰器用法: @property 修饰获取值的函数 @获取值的函数名.setter 修饰设置值的函数 property的类属性的用法: 类属性名=property(获取值的函数名, 设置值的函数名) 之后,就可以直接.上述的函数名来当做变量直接用 """#需求:定义学生类,私有属性age,通过property充当类属性用#1.定义学生类。classStudent:# 1.1 私有属性def__init__(self):self.__age=18# 1.2 提供公共的访问方式defget_age(self):returnself.__agedefset_age(self,age):# 这里可以做检验但一般不做,除非重要字段才做二次校验self.__age=age# 1.3 封装上述的公共方式为类属性:age=property(get_age,set_age)# 2.测试if__name__=='__main__':#2.1 创建学生对象student=Student()# 2.2 设置值并获取值student.age=10print(student.age)# 运行结果:10