一、复习

1.闭包:定义在函数内部的函数(被函数嵌套的函数)
2.装饰器:闭包的一个应用场景
-- 为一个函数添加新功能的工具
3.开放封闭原则:不能修改源代码,不能修改调用方式,但可以对外提供增加新功能的特性

小点:多个装饰器运行流程

def o1(func):
def inner(*args, **kwargs):
print('o1 ------------') #
result = func(*args, **kwargs)
print('o1 ============') #
return result
return inner def o2(func):
def inner(*args, **kwargs):
print('o2 ------------') #
result = func(*args, **kwargs)
print('o2 ============') #
return result
return inner
@o1
@o2
def fn2():
print('fn2 ============') #
fn2() # 函数调用位置
# # 执行流程:函数调用位置 => o1装饰器inner => o2装饰器inner => 本体fn2
# # => 回到o2装饰器inner =>回到o1装饰器inner => 回到函数调用位置 ##可通过debug走一遍看具体流程
def wrap1(func):
print('')
def inner1():
print('')
func() # 应该是自身的func
print('')
return inner1 def wrap2(func):
print('')
def inner2():
print('')
func() # 此处的func 是 inner1 即,运行 inner1() 等到上述执行完后在继续执行
print('')
return inner2
@wrap2 # func = wrap1() 执行返回inner1 即 func=inner1
@wrap1 # func = wrap2() 执行返回inner() 即 inner1 = inner2
def func():
print('') func() # 实际运行 inner2() #打印结果: 1,2,3,4,5,6,7
def wrap1(func):
print('')
def inner1():
print('')
func() # 此处的func是 inner2,即运行inner2()
print('')
return inner1 def wrap2(func):
print('')
def inner2():
print('')
func() # 此处为自身
print('')
return inner2
@wrap1 # func = wrap1() 执行返回inner1 本质上是 inner2 = inner1
@wrap2 # func = wrap2() 先执行返回inner2 即 func = inner2 代码的解释顺序决定的
def func():
print('') func() # func = inner2 而inner2=innser1 实际运行 inner1() #打印结果: 1,2,3,4,5,6,7
上述的差异,在于谁先给函数装饰,结果如上,逻辑暂没弄清

小点:多层嵌套的装饰器

def wrap(var):
def outer(func): # outer的参数是固定的,就是被装饰的函数对象
print(var)
def inner(*args, **kwargs):
print(111111111111111)
func(*args, **kwargs)
print(333333333333333)
return inner
return outer # 1.调用wrap返回outer
@wrap(0) # wrap(000) => outer => @outer => fn3 = outer(fn3)
##@wrap(0) 可看做是两种情况综合 先wrap(0),运行返回outer,
## 此时在运行@outer,接下来的是正常的装饰器节奏 def fn3():
print(222222222222222) #调用outer传入fn3返回inner给fn3
fn3() # # @wrap(000) # wrap(000) => outer => @outer => fn3 = outer(fn3) # # 3.调用fn3就是调用inner,在inner内部调用原fn3

二、迭代器

1、相关概念:

器:包含多个值得容器

迭代:循环反馈(一次从容器中取出一个值)

迭代器:从装有多个值的容器里取出一个值给外界

迭代器:从装有多个值得容器中一次取出一个值给外界

2、可迭代对象

对象:python中装有地址的一个变量

可迭代对象:该对象有_iter_()方法

可迭代对象通过调用_iter_()方法得到迭代器对象

3、迭代器对象

迭代器对象可以做到不依赖索引取值(一次从容器中取出一个值)

迭代器对象都存在_next_()方法,且通过该方法获取容器中的值,获取规则,从前往后一次一个

st1={3,2,6,5,9}   #不清楚集合为什么打印的结果是从小到大,而其他不是
iter_obj=st1._iter_()
print(iter_obj) #<set_iterator object at 0x00000000021E13A8> #迭代器对象取一个值就少一个值(重点掌握)
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
print(iter_obj.__next__()) #
print(iter_obj.__next__()) # #print(iter_obj.__next__()) #再加上一个,超出其范围,会报错
StopIteration ter_obj=st1._iter_() #若不加上这个迭代器对象,会输出结果为空,上面
已经取完其值
while True:
try:
ele = iter_obj.__next__()
print(ele)
except StopIteration: # 此处的try except 用来除去异常
# print("取完了") # 因为会存在无限循环,但是值不够的情况
break

4、for 循环

自带异常处理的while循环,自动获取被迭代对象的迭代器对象(即不需要人为添加._next_())

# for循环迭代器:
# -- 1.自动获取被迭代对象的迭代器对象;
# -- 2.在内部一次一次调用__next__()方法取值;
# -- 3.自动完成异常处理
for v in obj:
print(v)
if v == 2:
break print(obj.__iter__().__iter__().__iter__().__next__()) # 3 因为上面的for已经取了两个值
# print(obj.__iter__().__iter__().__iter__() is obj) # True
# 可迭代对象.__iter__()得到的是该对象的迭代器对象
# 迭代器对象.__iter__().__iter__()得到的就是迭代器对象本身

迭代器对象代码:

for v in 'abc'.__iter__():
print(v)
结果:
a
b
c for v in 'abc'.__iter__():
print(v)
结果:
a
b
c
# 为什么此处可以重复打印? 因为第二次重新给字符串装换到了迭代器对象
因此可以重复使用,而不是上面取完值后,下面没有输出结果
with open('abc.txt', 'r', encoding='utf-8') as f:
print(f.__next__())
print(f.__next__())
print(f.__next__()) #‘abc.txt’文件里存在多行数据,此时的print是一行打印一次,因此需要多个print

直接:

可迭代对象:即有有__iter__()方法的对象,调用该方法返回迭代器对象

str | list | tuple | dict | set | range() | file | 迭代器对象 | enumerate() | 生成器

迭代器对象:有__next__()方法的对象,也就是用该方法一次从迭代器对象中获取一个值,取出一个少一个

file | enumerate() | 生成器

重点:
1.从迭代器对象中取元素,取一个少一个,如果要从头开始去,需要重新获得拥有所有元素的迭代器对象
2.迭代器对象也有__iter__()方法,调用后得到的是自己本身(当前含义几个元素,得到的就只有几个元素的迭代器对象)

3、对于for循环迭代:

1.自动获取被迭代对象的迭代器对象
     2.在内部一次一次调用__next__()方法取值;
     3.自动完成异常处理

三、生成器

# 生成器:就是一个迭代器对象
# 包含yield关键字的函数就是生成器
# 该函数名()得到的是生成器对象,且不会执行函数体
# 在函数内部执行一次,在遇到下一个yield时停止,且可以拿到yield的返回值
def my_yield():
print('first')
yield 1
print('second')
yield 2
print('Third')
yield 3
g=my_yield() next(g)
next(g)
next(g)
#以下为结果: 只打印函数体
first
second
Third print(next(g)
print(next(g)
print(next(g)
#以下为结果: 函数体和返回值都打印
first
1
second
2
Third
3

打印生成器的结果1

def my_yield():
print('first')
yield 1
print('second')
yield 2
print('Third')
yield 3 for i in my_yield():
print(i) #下面为结果:
first
1
second
2
Third
3 yields=my_yield()
print(yields)
#以下为结果:
<generator object my_yield at 0x000000000216A390> yields=my_yield()
print(list(yields))
#以下为结果:
first
second
Third
[1, 2, 3]

打印生成器的结果2

总结:
按 顺序打印函数体和返回值:
for 循环 print(next(i)) 先打印函数体后打印返回值:
print(list(i)) 用其他类型数据转换 直接打印函数体:
next(i) 直接打印生成器地址:
print(i) 建议日常使用for循环和next方式取值

生成器打印结果总结


四‘枚举对象 ’
enumerate
通过for迭代器 循环遍历 可迭代对象,需要知道迭代的索引
#从上一次停止的位置紧着往下走,在再遇到下一个yield时停止,且可以拿到yield的返回值
# 生成器可以被for循环迭代
ls = [1, 3, 5, 7, 9]
for i, v in enumerate(ls):
print(i, v)
结果:

0 1
1 3
2 5
3 7

4 9

小点:
dict={'a':1,'b':2}
lis=[]
for i in enumerate(dict):
lis.append(i)
print(lis)
#[(0, 'a'), (1, 'b')] #此处可见 仅用一个值i就可将索引与对应的值导出
#可利用此种特性将数据成行打印 #也可利用两个参数,将其换行打印

  

python学习 day13 迭代器,生成器,枚举对象的更多相关文章

  1. Python学习 :迭代器&生成器

    列表生成式 列表生成式的操作顺序: 1.先依次来读取元素 for x 2.对元素进行操作 x*x 3.赋予变量 Eg.列表生成式方式一 a = [x*x for x in range(10)] pri ...

  2. Python学习day17 迭代器&生成器

    迭代器&生成器 1. 迭代器 1.1 迭代器 迭代:迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代" 迭代器:帮助对某种对象 ...

  3. python学习10—迭代器、三元表达式与生成器

    python学习10—迭代器.三元表达式与生成器 1. 迭代器协议 定义:对象必须提供一个next方法,执行该方法或者返回迭代中的下一项,或者返回一个StopIteration异常,以终止迭代(只能往 ...

  4. python 全栈开发,Day13(迭代器,生成器)

    一.迭代器 python 一切皆对象 能被for循环的对象就是可迭代对象 可迭代对象: str,list,tuple,dict,set,range 迭代器: f1文件句柄 dir打印该对象的所有操作方 ...

  5. Python学习之旅—生成器对象的send方法详解

    前言 在上一篇博客中,笔者带大家一起探讨了生成器与迭代器的本质原理和使用,本次博客将重点聚焦于生成器对象的send方法. 一.send方法详解  我们知道生成器对象本质上是一个迭代器.但是它比迭代器对 ...

  6. Python学习笔记之生成器、迭代器和装饰器

    这篇文章主要介绍 Python 中几个常用的高级特性,用好这几个特性可以让自己的代码更加 Pythonnic 哦 1.生成器 什么是生成器呢?简单来说,在 Python 中一边循环一边计算的机制称为 ...

  7. python学习-38迭代器和生成器

    迭代器和生成器 ---- 迭代器协议和for循环工作机制 1.迭代器协议:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么引起一个Stoplteration异常,以终止迭代(只能往 ...

  8. python各种模块,迭代器,生成器

    从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能) 本质就是.py结尾的python文件(文件名:test.py,对应的模块名就是test) 包:用来从逻辑上组织模块的,本质就是一个目 ...

  9. python杂记-4(迭代器&生成器)

    #!/usr/bin/env python# -*- coding: utf-8 -*-#1.迭代器&生成器#生成器#正确的方法是使用for循环,因为generator也是可迭代对象:g = ...

随机推荐

  1. Python取整及保留小数小结

    1.int() 向下取整 内置函数  n = 3.75 print(int(n))>>> 3 n = 3.25 print(int(n))>>> 3 2.round ...

  2. 怎样从外网访问内网Tornado

    外网访问内网Tornado 本地安装了Tornado,只能在局域网内访问,怎样从外网也能访问本地Tornado? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Tornado 默认安装 ...

  3. 剑指offer(16)合并两个排序的链表

    题目描述 输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则. 题目分析 重点抓住这两个链表都是单挑递增的,因此我们只需要不断地比较他们的头结点就行,明显这是个 ...

  4. 剑指offer(33)丑数

    题目描述 把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 题目分析 ...

  5. python scrapy baidu image【转】

    原 https://github.com/vivianLL/baidupictures #!/usr/bin/env Python # coding=utf-8 #__author__ = 'leil ...

  6. Canonical Coin Systems【完全背包】

    问题 C: Canonical Coin Systems 时间限制: 1 Sec  内存限制: 128 MB 提交: 200  解决: 31 [提交] [状态] [命题人:admin] 题目描述 A ...

  7. Ipan笔记-2

    其实二级联动下拉选择框很简单的, 参考: https://www.cnblogs.com/zhangmiaomiao/p/6013533.html ============== 关于$.each和 $ ...

  8. Cookie和Seesion

    会话跟踪技术 1 什么是会话跟踪技术 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而10 ...

  9. 补充一下 sizeof

    sizeof是一个运算符,给出某个类型或变量在内存中所占据的字节数 sizeof(int) //告诉你int占据几个字节 sizeof(i) //告诉你i这个变量占据几个字节 注:sizeof是静态运 ...

  10. Nearest neighbor graph | 近邻图

    最近在开发一套自己的单细胞分析方法,所以copy paste事业有所停顿. 实例: R eNetIt v0.1-1 data(ralu.site) # Saturated spatial graph ...