一、复习

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. 进程间通信之信号量、消息队列、共享内存(system v的shm和mmap)+信号signal

    进程间通信方式有:System v unix提供3种进程间通信IPC:信号量.消息队列.共享内存.此外,传统方法:信号.管道.socket套接字. [注意上述6种方式只能用户层进程间通信.内核内部有类 ...

  2. 防火墙iptables 设置

    在服务器上架了一个tomcat,指定好端口号,我就开始访问,未果! 公司对服务器(RedHat)端口限制,可谓是滴水不漏! 用iptables 查看防火墙设置: Shell代码 iptables -n ...

  3. ps | grep排除grep这个进程

    我们经常用ps | grep xxx来查询是否存在某进程,但默认情况下会将grep这个命令也作为结果返回,这样无论是否存在查询的进程,该命令的返回值都是0. 要避免这种情况可以使用grep的-v参数, ...

  4. 剑指offer(54)字符流中第一个不重复的数字

    题目描述 请实现一个函数用来找出字符流中第一个只出现一次的字符.例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g".当从该字符流中读出 ...

  5. JS(JavaScript)的初了解3(更新中···)

    1. {} 在JS中我们把它叫代码块.如果代码块里的内容没有执行完,语句不会向下执行. 代码块是一个独立的整体.如果JS中某一条语句出错,那么就会在此终止不会向下执行. 2. 循环语句 循环,就是对一 ...

  6. css的再深入6(更新中···)

    background-position  雪碧图 我们的html和css中有三个属性可以向服务器发送请求,src href url. overflow (1) 值hidden 超出就隐藏 (2) 值s ...

  7. SAP的软件维护费用,交还是不交?

    SAP的软件维护费用,交还是不交? 首先我们要明确一点,什么是软件维护费用?     软件维护费用是指在企业购买了软件厂商的软件产品之后,软件厂商每年按照一定比例向企业收取一定的技术支持维护费用.收取 ...

  8. Python3文件操作1 --Python3

    1.文件的两种类型 文本文件:由单一特定的编码字符组成(如:txt文件) 二进制文件:直接由比特0和比特1组成,文件内部数据组织格式与文件的用途有关(视频.图片) 2.文件主要操作概述 Python对 ...

  9. eclipse get set 自动添加注释

    编码的时候通常要用到 JavaBean ,而在我们经常把注释写在字段上面,但生成的Get/Set方法不会生成,通过修改Eclipse源码可解决,直接上例子: /** * 员工ID */ private ...

  10. web中静态资源和动态资源的概念及区别

    1.静态资源和动态资源的概念 简单来说: 静态资源:一般客户端发送请求到web服务器,web服务器从内存在取到相应的文件,返回给客户端,客户端解析并渲染显示出来. 动态资源:一般客户端请求的动态资源, ...