生成器对象(自定义迭代器),自定义range方法,模块
自定义迭代器
一 、生成器与yield
'''
我们得到一个迭代器通常都是调用可迭代对象的__iter__方法 ,例如 list.iter() 得到一个迭代器,
但是当list很大时候,就违背了python的初衷,假设我们要创造一个包含1000w个值的可迭代对象,总不可能先把
这1000w个值放入列表,然后调用__iter__() 方法吧,太占内存 ,必须得提供一种机制打破python内置的产生
迭代器的方式 ,所以自定义迭代器应运而生,即生成器。
在Python中, 一边循环一边计算的机制, 称为生成器:generator, 若函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的返回值即生成器对象
'''
自定义range函数
def my_range(start,stop,step=1): # 自定义range函数
print('start...')
while start < stop:
yield start
start+=step
print('end...')
g=my_range(0,3)
print(g)
<generator object my_range at 0x01E2A808>
如何得到自定义的迭代器:
在函数内一旦存在yield关键字,调用函数并不会执行函数体代码
会返回一个生成器对象,生成器即自定义的迭代器
"""
如果函数体代码中含有多个yield关键字 执行一次__next__返回后面的值并且让代码停留在yield位置
再次执行__next__基于上次的位置继续往后执行到下一个yield关键字处
如果没有了 再执行也会报错 StopIteration
"""
生成器本身就是一个迭代器
print(g.__iter__) # <method-wrapper '__iter__' of generator object at 0x01AFB878>
print(g.__next__) # <method-wrapper '__next__' of generator object at 0x01AFB878>
'''生成器内置有__iter__和__next__方法,所以生成器本身就是一个迭代器'''
用next(生成器)触发生成器所对应函数的执行
print(next(g)) # 触发函数执行直到遇到yield则停止,将yield后的值返回,并在当前位置挂起函数
start...
0
print(next(g)) # 再次调用next(g),函数从上次暂停的位置继续执行,直到重新遇到yield...
1
print(next(g)) # 周而复始...
2
print(next(g)) # 触发函数执行没有遇到yield则无值返回,即取值完毕抛出异常结束迭代
end...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
既然生成器对象属于迭代器,那么必然可以使用for循环迭代,如下:
for i in g:
print(i)
执行结果:
start...
0
1
2
end...
'''
有了yield关键字,我们就有了一种自定义迭代器的实现方式。yield可以用于返回值,但不同于
return,函数一旦遇到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值
'''
yield关键字作用
yield最简单的解释
yield可以理解为一个return操作,但是和return又有很大的区别,执行完return,当前函数就终止了,
函数内部的所有数据,所占的内存空间,全部都没有了。而yield在返回数据的同时,还保存了当前的执行
内容,当你再一次调用这个函数时,他会找到你在此函数中的yield关键字,然后从yield的下一句开始执行。
例一
def num_print():
print('yield_1')
yield 'yield_1 return'
print('yield_2')
yield 'yield_2 return'
print('yield_3')
yield 'yield_3 return'
print('yield_4')
yield 'yield_4 return'
for i in num_print():
print('i:',i)
执行结果:
yield_1
i: yield_1 return
yield_2
i: yield_2 return
yield_3
i: yield_3 return
yield_4
i: yield_4 return
'''
上边在循环处一直在调用函数,可以看出每次调用函数,他会执行到yield进行返回,然后下一次调用时
他会从上一次执行yield的后边继续执行
'''
例二(可以接收外界的传值(了解))
def play():
while True:
game = yield
print(f'玩{game}')
res = play()
res.__next__()
res.send('LOL')
执行结果:
玩LOL
生成器表达式
语法
(返回值 for 元素 in 可迭代对象 if 条件)
返回一个生成器,生成器也是一个对象,属于中间值
g = (i ** 2 for i in range(5)) # 将使用生成器表达式得到的生成器对象赋给一个变量g
print(g)
'''输出:
<generator object <genexpr> at 0x109835b10>
'''
print(g.__next__())
"""生成器内部的代码只有在调用__next__迭代取值的时候才会执行"""
主要功能是,代码优化,节省存储空间。
生成器表达式和列表生成式的区别

模块
简介
在Python中有一个概念叫做模块(module),这个和C语言中的头文件以及Java中的包很类似,比如在
Python中要调用sqrt函数,必须用import关键字引入math这个模块
说的通俗点:模块就好比是工具包,要想使用这个工具包中的工具(就好比函数),就需要导入这个模块
模块的来源
目前有3个来源
1.内置的模块
无需下载 解释器自带 直接导入使用即可
2.自定义模块
自己写的代码 封装成模块 自己用或者发布到网上供别人使用
3.第三方模块
别人写的发布到网上的 可以下载使用的模块(很多牛逼的模块都是第三方)
导入模块的方法
第一种:import
在Python中用关键字import来引入某个模块,比如要引用模块math,就可以在文件最开始的地方用
import math来引入。
当解释器遇到import语句,如果模块在当前的搜索路径就会被导入。
在调用math模块中的函数时,必须这样引用:
模块名.函数名
这种方式必须加上模块名调用,因为可能存在这样一种情况:在多个模块中含有相同名称的函数,此时如
果只是通过函数名来调用,解释器无法知道到底要调用哪个函数。所以如果像上述这样引入模块的时候,调用
函数必须加上模块名。
有时候我们只需要用到模块中的某个函数,只需要引入该函数即可,此时可以用下面方法实现:
from模块名import函数名1,函数名2....
'''
通过这种方式引入的时候,调用函数时只能给出函数名,不能给出模块名,但是当两个模块中含有相同
名称函数的时候,后面一次引入会覆盖前一次引入。也就是说假如模块A中有函数function( ),在模块B中也
有函数function( ),如果引入A中的function在先、B中的function在后,那么当调用function函数的时
候,是去执行模块B中的function函数。
'''
如果想一次性引入math中所有的东西,还可以通过from math import *来实现
第二种:from…import
Python的from语句让你从模块中导入一个指定的部分到当前命名空间中
语法如下:
from 模块名 import name,func1,func2(需要导入的函数或者变量)
例如,要导入模块fib的fibonacci函数,使用如下语句:
from fib import fibonacci
注意:
不会把整个fib模块导入到当前的命名空间中,它只会将fib里的fibonacci单个引入
"""
1.重复导入也只会导入一次
2.使用模块名称空间中的名字不需要加模块名前缀 直接使用即可
3.但是from...import的句式会产生名字冲突的问题
在使用的时候 一定要避免名字冲突
4.使用from...import的句式 只能使用import后面出现的名字
from...import...可以简单的翻译成中文
从...里面拿...来用 没有提到的都不能用 指名道姓
"""
补充
导入模块起别名,导入模块是对模块进行重命名,也就是给模块起一个别名。
import 模块名 as mod
'''
在后续使用时就可以使用这个别名
比如模块名或者变量名很复杂 可以起别名简写
'''
from 模块名 import *
'''
*表示md里面所有的名字 from...import的句 式也可以导入所有的名字
如果模块文件中使用了__all__限制可以使用的名字 那么*号就会失效 依据__all__后面列举的名字
'''
图文介绍两种导包


生成器对象(自定义迭代器),自定义range方法,模块的更多相关文章
- Python自动化--语言基础5--面向对象、迭代器、range和切片的区分
面向对象 一.面向对象代码示例: 1 class Test(): #类的定义 2 car = "buick" #类变量,定义在类里方法外,可被对象直接调用,具有全局效果 3 def ...
- python学习Day14 带参装饰器、可迭代对象、迭代器对象、for 迭代器工作原理、枚举对象、生成器
复习 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.返回内部函数对象----> 延迟执行, 开放封闭原则: 功能可以拓展,但源代 ...
- day 13 迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象
迭代器大概念 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值( ...
- python之迭代器、可迭代对象、生成器、生成器对象、枚举类型
迭代器 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值(只能从 ...
- ECMAScript 2015 迭代器协议:实现自定义迭代器
迭代器协议定义了一种标准的方式来产生一个有限或无限序列的值,并且当所有的值都已经被迭代后,就会有一个默认的返回值. 当一个对象只有满足下述条件才会被认为是一个迭代器:它实现了一个 next() 的方法 ...
- python14 1.带参装饰器 | wrapper 了了解 # 2.迭代器 ***** # 可迭代对象 # 迭代器对象 # for迭代器 # 枚举对象
## 复习 '''函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 ...
- day14带参装饰器,迭代器,可迭代对象 , 迭代器对象 ,for迭代器 , 枚举对象
复习 ''' 函数的嵌套定义:在函数内部定义另一个函数 闭包:被嵌套的函数 -- 1.外层通过形参给内层函数传参 -- 2.验证执行 开放封闭原则: 功能可以拓展,但源代码与调用方式都不可以改变 装饰 ...
- Two---python循环语句/迭代器生成器/yield与return/自定义函数与匿名函数/参数传递
python基础02 条件控制 python条件语句是通过一条或多条语句的执行结果(Ture或者False)来执行的代码块 python中用elif代替了else if,所以if语句的关键字为:if- ...
- Python 3.x自定义迭代器对象
Python 3.x与Python 2.x之间存在着较多的语法细节差异.今天在看Python核心编程的时候,说到了自定义迭代器对象.于是动手将源码打了一遍,原书代码如下: class AnyIter( ...
随机推荐
- Servlet与JSP之间相互传值问题
一.JSP向Servlet传值 JSP向Servlet传值的方式有三种:URL后面跟参数.form表单提交.在JSP内置对象Session设置值. URL后面跟参数 JSP文件:<a href= ...
- Redis++:Redis做分布式锁真的靠谱吗
Redis做分布式锁真的靠谱吗 Redis的分布式锁可以通过Lua进行实现,通过setnx和expire命令连用的方式 || 也可以使用高版本的方法同时设置失效时间,但是假如在以下情况下,就会造成无锁 ...
- 无需Flash录视频——HTML5中级进阶
前言 HTML5的权限越来越大了,浏览器可以直接调用摄像头.麦克风了,好激动啊.我们要用纯洁的HTML代码造出自己的天地. 视频采集 本篇介绍的栗子 都是在chrome 47 版本以上的,低版本的可能 ...
- 前端网络安全——Cookies
一.Cookies特性 1.前端数据存储 2.后端通过http头设置 3.请求时通过http头传给后端 4.前端可读写 5.遵守同源策略 二.Cookies内容 1.域名 2.有效期,删除cookie ...
- CCF201912-2 回收站选址
解题思路:这道题唬人的在于坐标有正有负哈,刚开始不知道怎么下爪,仔细思考过后,我可是会面向对象编程的啊哈哈哈哈,我可是最喜欢封装了哈哈哈哈. 1.首先可以把每个点用一个结构体来定义,包含他的x,y坐标 ...
- pip导出项目依赖包名称及版本,再安装命令
A导出依赖 pip freeze >requirements.txt B导入安装依赖 pip install -r requirements.txt 使用下面的命令安装依赖能自动跳过安装错误的依 ...
- 帝国cms修改成https后后台登陆空白的解决办法
以下方法适用帝国cms7.5版本: 7.5版本已经有了http和https自动识别,但是因为一些疑难杂症的原因,自动识别判断的不准,后台登录也是空白, 我们可以打开e/config.php查找'htt ...
- drf的JWT认证
JWT认证(5星) token发展史 在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证.我们不再使用Session认证机制,而使用Json Web Token(本质就是tok ...
- 背包问题dp的初步总结
背包问题 01背包 给定的物体只有0个和1个,只有选与不选的划分,其状态转移方程时由i-1行推出,所以第二层循环是由j=m,递减到v[i]的. for(int i=1;i<=n;i++){ fo ...
- 机器学习实战:用SVD压缩图像
前文我们了解了奇异值分解(SVD)的原理,今天就实战一下,用矩阵的奇异值分解对图片进行压缩. Learn by doing 我做了一个在线的图像压缩应用,大家可以感受一下. https://huggi ...