1.什么是迭代 迭代就是更新换代,但是每次迭代的过程都需要依赖上一次的结果。最常见的例子就是:游戏的更新 2.可迭代对象 内置有__iter__方法的都可以称之为是可迭代对象 字符串、列表、字典、元组、集合、文件对象 ''' 1.__iter__类似代码的读法>>>:双下方法 2.简便方法 __iter__ iter() __next__ next() ''' 3.迭代器对象 # 1.迭代器对象的特征 有__iter__和__next__方法 # 2.如何产生迭代器对象 可迭代对象调用__iter__方法就会变成迭代器对象 ''' 迭代器对象如果再次调用__iter__方法还是迭代器对象本身 ''' # 3.迭代器对象的作用 能够存储数据并节省存储空间,是一种优化的数据存储形式 # 4.迭代器对象取值的特征 内部数据每取一次就会少一个,取完了内部数据也就空了(但是是同一个迭代器) # 5.迭代器对象的主要应用 提供了一种不依赖与索引取值的方式 是对无序容器类型进行迭代取值的必要
异常处理的语法结构: try: 可能会出错的代码 except 出错的类型1 as e: 针对出错类型的解决措施 except 出错的类型2 as e: 针对出错类型的解决措施 except 出错的类型3 as e: 针对出错类型的解决措施 except 万能异常(Exception) as e: 统一出错的解决措施 else: 可能会出错的代码没有出错 执行完毕后就会走else finally: 无论上面怎么走 最后都要走finally
res = 可迭代对象.__iter__() while True: try: print(res.__next__) except StopIteration as e: break # 万能异常可以捕获很多常见的异常类型
# 本质上还是迭代器,只是通过自己写代码产生的 其中也是包含: __iter__和__next__方法的 例: def index(): print('are you kidding me ?') yield 123 yield 123, 111 print('must be forgot me') yield 666 '''生成器对象也是节省存储空间的 特性与迭代器对象一致''' ''' 当函数体代码中含有yield关键字 第一次调用函数并不会执行函数体代码 而是将函数变成了生成器 ''' # 没有调用之前,它就是一个普通的函数 print(index) # <function index at 0x00000269CC501F28> # 加括号调用并接收结果:不执行代码,而是变成生成器对象(迭代器) res = index() print(rse) # <generator object index at 0x00000269CC992E08> # 变成生成器对象之后调用__next__就会开始执行函数体代码 res.__next__() # are you kidding me ? print(res.__next__()) # are you kidding me ? # 123 print(res.__next__()) # # are you kidding me ? # 123 # (123, 111) print(res.__next__()) # are you kidding me ? # 123 # (123, 111) # must be forgot me # 666 print(res.__next__()) # 生成器对象内容被取完 # 报错,因为没东西取了 # StopIteration for i in res: print(i) ''' 如果函数体代码中含有多个yield关键字 执行一次__next__返回后面的值并且让代码停留在yield位置 再次执行__next__基于上次的位置继续往后执行到下一个yield关键字处 如果没有了 再执行也会报错 StopIteration '''
# range方法其实是一个可迭代对象 for i in range(1, 10): print(i) 问题:通过生成器模拟range方法 def my_range(): pass for i in my_range(1, 10): print(i) # 首先以两个参数的range方法为例 def my_range(start, end=None, step=1): if not end: # 没有给end传值 my_range(10) end = start start = 0 'end可以不传值,应该设置成默认参数,end=None' '将形参进行调换 end = start' while start < end: yield start start += step '第三个参数step默认值为1' '每次递增就只用递增step的值就好了 start += step' # 先建大框架,然后再考虑参数的情况,整体状态如下 def my_range(start, end=None, step=1): if not end: end = start start = 0 while start < end: yield start start += step for i in my_range(1,10): print(i) ''' 1 2 3 4 5 6 7 8 9 '''
yield关键字有以下的作用: 1.在函数体代码中出现,可以将函数变成生成器 2.在执行的过程中可以将跟在yield后面的值返回出去,类似于return的返回作用 3.而且它还可以暂停住代码的运行 4.最后还有一个接收外界传值的作用 def eat(name): print(f'{name}可以吃饭了) while True: food = yield print(f'{name}正在吃什么{food}) res = eat('老赵') # 想执行一次代码,用双下next方法,如果想多次执行可以用for循环 res.__next__() # 老赵可以吃饭了 res.__next__() # 老赵正在吃什么None res.__next__() # 老赵正在吃什么None # 问,现在在food值为None的情况下如何传值呢 'send方法可以给yield传值,而且还能自动调用一次双下next方法' res.send('蛋糕') # 老赵正在吃什么蛋糕 res.send('烩面') # 老赵正在吃什么烩面
功能:为了节省存储空间 res = (i for i in 'jason') print(res) # <generator object <genexpr> at 0x1130cf468> print(res.__next__()) '生成器内部的代码只有在调用__next__迭代取值的时候才会执行' # 普通的求和函数 def add(n, i): return n + i # 再定义一个函数test def test(): for i in range(4): yield i # 将test函数变成生成器对象 res = test() # 一个for循环 for n in (1, 10): res = (add(n, i) for i in res) """ 第一次for循环 g = (add(n, i) for i in g) 第二次for循环 g = (add(10, i) for i in (add(10, i) for i in g)) """ res = list(g) # list底层就是for循环,相当于对g做了迭代取值操作 print(res) res = [20, 21, 22, 23]
''' import time # 导入模块 time.time() # 调用模块内的方法 ''' # 1.什么是模块? 模块就是某一特定功能方向的方法,可以直接调用使用 # 2.为什么要用模块? 极大地提升开发效率,可以省去很多时间从而完成需求的功能 # 3.模块的三种来源 1.内置的模块 无需下载,python解释器自带,直接导入使用即可 2.自定义模块 自己写的符合某一功能的代码,封装成模块,自己用或者发布到网上供别人使用 3.第三方模块 别人写的发布到网上的,可以下载使用的模块(很多大佬都是写第三方模块的) # 4.模块的四种表现形式 1.使用python代码编写的py文件 # 掌握 2.多个py文件组成的文件夹(包) # 掌握 3.已被编译为共享库或DLL的c或C++扩展(了解) 4.使用C编写并链接到python解释器的内置模块(了解)
导入的方法有两种: # 方式一: import方式...句式 import xxx(你需要导入的模块的名称) '首先必须明白谁是执行文件谁是被导入文件(模块)' ''' 模块中 .py是执行文件 md.py文件是被导入文件(模块) 模块只需要导入一次即可,不需要重复导入 ''' 然而导入模块的内部发生了什么事呢? 1.执行当前文件 产生一个当前文件的名称空间 2.执行import句式 导入模块文件(即执行模块文件代码产生模块文件的名称空间) 3.在当前文件的名称空间中产生一个模块的名字 指向模块的名称空间 4.通过该名字就可以使用到模块名称空间中的所有数据 ps:相同的模块反复被导入只会执行一次 print(md.name) # 获取模块名称空间中的name print(name) # 获取当前名称空间中的name import md money = 666 md.change() print(money) # 方式二: from...import...句式 from md import name,money,read1 print(name) # jasonNB name = 'kevin' print(name) # kevin print(money) # 报错 from md import name 只使用模块中的name名字 read1() ''' 执行当前文件产生一个名称空间 执行导入语句,运行模块文件产生名称空间存放运行过程中的所有名称 将import后面的名字直接拿到当前执行文件中 ''' # 注意 1.模块即使重复导入也只能导入一次 2.模块空间名称空间中的名字不需要加模块名前缀,大可直接使用 3.但是from...import的句式会产生名字冲突的问题,所以使用的时候要注意 4.使用from...import的句式,只能使用import后面出现的名字
1.模块可以取别名,也就是简写(在使用率的情况下) import md as m print(m.name) from md import name as n print(n) 2.连续导入多个模块或者变量名 import time, sys, md from md import name, read1, read2 """ 连续导入多个模块,这多个模块最好有相似的功能部分,如果没有建议分开导入 如果是同一个模块下的多个变量名则影响较小 """ import time import sys import md 3.通用导入 from md import * ''' * 代表导入模块md中的所有变量名字,from...import的句式也可以导入所有的名字 ''' 如果模块文件中使用了双下all限制可以使用的名字,那么*号就会失效,依据双下all后面列举的名字
今天主要学习了模块的一些使用及方法,受益颇深,原来导入模块也有这么多讲究,着实要好好想想思考思考