一、反射

反射就是通过 内置函数getattr() 以字符串的形式导入模块,以字符串的形式调用模块/对象里方法

l=['add','del','set','find']
for i in l:
print(i)
choice=input("请输入您需要的操作:".strip())
mode=__import__(choice) #相当于 import 模块
getattr(mode,choice[0])() #获取 模块里定义的方法(函数)并且执行;

二、迭代器

Python的数据类型分为

不可迭代类型(数字、布尔值)

可迭代类型(字符串、列表、元组、集合、字典、文件句柄、range、枚举....),

这些可迭代对象有一个共同的特征就是可以被for循环,而不能被for循环的都是不可迭代对象;

那么他们为什么可以被for循环呢?

Python种一切皆对象体现在+/-....语法都可以被Python解释隐藏调用一些双下(__add__。。。。)方法也就是已经被C语言实现好了的方法,当解释器遇到语法就会调用其对应的双下方法,进而返回结果;

顺腾摸瓜我们就来看一下这些可迭代对象中都隐藏了什么__共同的双下___方法;

ret=set(dir({})) & set(dir([])) & set(dir(()))
print(ret) {
'__reduce__', '__eq__', '__reduce_ex__', '__getitem__', '__len__', '__sizeof__', '__getattribute__', '__format__', '__subclasshook__', '__delattr__', '__gt__', '__setattr__', '__hash__', '__contains__', '__class__', '__iter__', '__doc__', '__le__', '__new__', '__init_subclass__', '__repr__', '__ge__', '__lt__', '__ne__', '__dir__', '__str__', '__init__' }
print('__iter__' in set(dir({})))      #可迭代对象拥有__iter__双下方法
print('__iter__' in set(dir(True))) #不可迭代对象没有__iter__双下方法

得知所有的可迭代对象内部都有1个__inter__()双下方法,这就是Python中规定的可迭代协议;

所以在for循环执行之前会去寻找循环对象的__inter__方法,如果没有__inter__方法,循环会直接报错,这是不可以迭代的对象;

l1=[1,2,3,4]
print(l1.__iter__())

所有可迭代对象执行__iter__双下方法之后都会返回1个迭代器

l1=[1,2,3,4]
print(set(dir(l1.__iter__())) - set(dir({}))) #{'__setstate__', '__next__', '__length_hint__'}

迭代器比可迭代对象多了3个双下方法分别是:__setstate__, __next__, __length_hint__

class A():
def __iter__():pass
def __next__():pass a=A() from collections import Iterable
from collections import Iterator print(isinstance(a,Iterable))#可迭代对象
print(isinstance(a,Iterator))#迭代器

迭代器协议:实现了__iter__ + __next__方法就是一个迭代器;

迭代器的作用:

1.由于可迭代对象生成数据是不会一下生成全部的数据,而是生成一个迭代器,然后1个1个得吐给你,所以就避免可生成大数据导致内存撑爆;

generater=range(10000000000000000000000000)        #迭代器把数字1个1个得吐出来,不会占用1大块内存,而是随着for循环/__next__()1个1个得生成;
for n in generater: #随着for循环1个1个得取处迭代器中值
print(n) #big_data=list(range(10000000000000000000000000)) #会把数据1次生成,如果数据量过大,容易沾满内存

2.for循环是 对可迭代协议的实现

为啥列表/字典这些可迭代对象,没有__next__方法,容器中的元素也可以被 for循环出来呢?

因为for循环先执行了 [].__iter()__()把可迭代对象中__iter__()方法returen的结果组成 1个迭代器

然后1次1次得执行 [].__iter()__()__next__()把元素1个1个得获取出来。

#Python中for 循环的原理
list1=['','','','','']
g=list1.__iter__() #第1步:可迭代对象执行__iter__()得到1个生成器g
print(g.__next__()) #第2步:生成器g.__next__()遍历数据
print(g.__next__())
print(g.__next__())
print(g.__next__())

迭代器的应用场景

在平时写代码的过程中,需要产生大量的数据,但1次性全部生成又会导致内存占用量大,就可以使用迭代器协议,先生成迭代器,然后1个1个得吐出数据;

三、生成器

生成器的本质还是迭代器,可不过这个迭代器是程序员自己实现的;

实现生成器有2种方式:

方式1:yield写生成器函数

def func():                #普通函数
return 'zhanggen' ret=func()
print(ret)
------------------------------------------------------------------
def generator(): #0.生成器函数:函数内部包含yield关键字,就是生成器函数
yield 'zhang'
yield 'gen' g= generator() #1.生成器函数被调用后,得到1个生成器也就是迭代器作为返回值。
print(g.__next__()) #2.使用__next__()从里面取值
print(g.__next__())

使用生成器生成1000000个哇哈哈哈,只获取前50个

def wahaha():
for i in range(1000000):
yield "wahaha%s" %i g=wahaha()
print (g.__next__())#wahaha0 count=0 #获取前50个
for i in g:
count+=1
if count<=50:
print('for循环....%s'%i)

监听文件的输入,然后过滤用户输入的关键字

方式2:生成器表达式

g=(i for i in range(1,100))

print(g.__next__())

 四、生成器进阶

send语法

send的作用和next类似,不同的是send可以在获取生成器函数里面 下1个yield 值的同时,还可以在上1个yield 值的右边send1个值到生成器函数里面。

def generator():
print(123)
num=yield 1 #Python解释器当遇到1个等号时 先执行右边的yield 1,然后赋值num=yield 1
print('send传入的值',num)
print(456)
num1=yield 2
print(num1)
yield 3
g=generator()
print(g.__next__()) #第一次调用生成器时不能使用 send
print(g.send('hello'))#send的效果和__next__效果一样
print(g.send('hello1'))#send的效果和__next__效果一样
print(g.__next__())#最后1次调用生成器不使用 send

使用send的注意事项:

综上所述send的功能,send不可以 第1次和最后1次调用生成器时使用。

如何让1个生成器,无限的yield值 ,不会遇到  StopIteration异常。

def average():
print('start')
num=0
while True:#下次调用 __next__依然在while循环里面
num+=4
yield num #4 8 12 16... g=average() print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())

使用sen不断求平均值

#不断得计算平均值
def average():
sum_=0
count_=0
avg_=0
while True:
num_=yield avg_
sum_+=num_
count_+=1
print(sum_,num_,count_)
avg_=sum_/count_ avg_g=average()
avg_g.__next__()
print(avg_g.send(10))
print(avg_g.send(12))
print(avg_g.send(15))
print(avg_g.send(16))

 yield from 语法

yield from 帮助我们从序列数据类型里1个1个得yield 出每1个元素,而不是使用 for 循环

def generator():
a='abcde'
b=''
yield a
yield b
'''
abcde
12345
'''
g=generator()
for i in g:
print(i) def generator():
a='abcde'
b=''
yield from a #帮助我们从序列数据类型里,1个1个yield 出每个元素,而不是使用 for 循环。
yield from b g=generator()
for i in g:
print(i) '''
a
b
c
d
e
1
2
3
4
5 '''

chain多个生成器

def coroutine1(n):
print('我这coroutine1里面')
yield ''
yield '' def coroutine2(n):
print('我这coroutine2里面')
yield ''
yield ''

def func(n):
print('我在func里面')
yield from coroutine1(n) #yield from 相当于1个中间件,可以在1个函数里面 直接 把其他生成器里所有yield的值获取到
yield from coroutine2(n) g=func(2)
print(next(g))
print(next(g))
print(next(g))
print(next(g)) '''
我这coroutine1里面
1
2
我这coroutine2里面
3
4
'''

yield from新语法

参考

Python之 反射、迭代器、生成器的更多相关文章

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

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

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

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

  3. python基础6 迭代器 生成器

    可迭代的:内部含有__iter__方法的数据类型叫可迭代的,也叫迭代对象实现了迭代协议的对象 运用dir()方法来测试一个数据类型是不是可迭代的的. 迭代器协议是指:对象需要提供next方法,它要么返 ...

  4. python中的迭代器&&生成器&&装饰器

    迭代器iterator 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外, ...

  5. Python入门之迭代器/生成器/yield的表达方式/面向过程编程

    本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...

  6. python中的迭代器 生成器 装饰器

    什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,_ ...

  7. Python函数系列-迭代器,生成器

    一 迭代器 一 迭代的概念 #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不 ...

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

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

  9. python第四周迭代器生成器序列化面向过程递归

      第一节装饰器复习和知识储备------------ 第一节装饰器复习和知识储备------------ def wrapper(*args,**kwargs): index(*args,**kwa ...

  10. python装饰器,迭代器,生成器,协程

    python装饰器[1] 首先先明白以下两点 #嵌套函数 def out1(): def inner1(): print(1234) inner1()#当没有加入inner时out()不会打印输出12 ...

随机推荐

  1. oracle 使用问题

    12541: 典型的listener.ora 文件内容: SID_LIST_LISTENER =   (注册到监听器的service name所在区域)  (SID_LIST =    (SID_DE ...

  2. django优化--ORM优缺点

    谈Django绕不开ORM ORM : ORM概念,ORM特点,ORM 的优点,ORM 的缺点 orm : 对象关系映射 (Object Relational Mapping) ,用于实现面向对象编程 ...

  3. 2019-2020-1 20199319《Linux内核原理与分析》第八周作业

    可执行程序工作原理 ELF目标文件格式 1.目标文件(ABI,应用程序二进制接口):编译器生成的文件. 2.目标文件的格式:out格式.COFF格式.PE(windows)格式.ELF(Linux)格 ...

  4. PAT Basic 1019 数字黑洞 (20 分)

    给定任一个各位数字不完全相同的 4 位正整数,如果我们先把 4 个数字按非递增排序,再按非递减排序,然后用第 1 个数字减第 2 个数字,将得到一个新的数字.一直重复这样做,我们很快会停在有“数字黑洞 ...

  5. 宝塔linux面板命令大全 - 宝塔面板

    安装宝塔 Centos安装脚本 yum install -y wget && wget -O install.sh http://download.bt.cn/install/inst ...

  6. 我说CMMI之六:CMMI的评估--转载

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/dylanren/article/deta ...

  7. Leetcode练习题21. Merge Two Sorted Lists

    题目描述(easy) Merge Two Sorted Lists Merge two sorted linked lists and return it as a new list. The new ...

  8. docker运用

    由于目前工作中不使用docker 时间长了,下一个项目中要使用docker ,记录一下docker的运用 1:docker的部署 yum install -y yum-utils device-map ...

  9. itertools模块、排列、组合、算法

    关于列表重组的python小题 题目一:给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集).             说明:解集不能包含重复的子集. 示例:输入: nums = ...

  10. CSS定位——文档流定位

    关于CSS的定位机制Ⅰ ㈠概念 对于盒子模型来说,也就是页面元素,这些盒子究竟在页面的什么位置,怎样排列它,那么找到它的位置,确定它的位置,这个就是定位机制所决定的. ㈡分类 文档流, 浮动定位,层定 ...