python三大器_Python - 三大器 迭代器,生层器,装饰器

Python - 三大器 迭代器,生层器,装饰器

在介绍三大器之前先来了解一下容器和可迭代对象...

一. 容器

容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中。通常这类数据结构把所有的元素存储在内存中(也有一些特例,并不是所有的元素都放在内存,比如迭代器和生成器对象)在Python中,常见的容器对象有:

list, deque...

set, frozensets(不可变集合)...

dict, defaultdict, OrderedDict, Counter...

tuple, namedtuple...

str

容器的概念就像一个盒子,可以往里面装东西.当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,set,tuples都是容器对象:

>>> assert 1 in [1, 2, 3] # lists

>>> assert 4 not in [1, 2, 3]

>>> assert 1 in {1, 2, 3} # sets

>>> assert 4 not in {1, 2, 3}

>>> assert 1 in (1, 2, 3) # tuples

>>> assert 4 not in (1, 2, 3)

询问某元素是否在dict中用dict的中key:

>>> d = {1: 'foo', 2: 'bar', 3: 'qux'}

>>> assert 1 in d

>>> assert 'foo' not in d # 'foo' 不是dict中的元素

询问某substring是否在string中:

>>> s = 'foobar'

>>> assert 'b' in s

>>> assert 'x' not in s

>>> assert 'foo' in s

尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力,当然并不是所有的容器都是可迭代的,比如:Bloom filter,虽然Bloom filter可以用来检测某个元素是否包含在容器中,但是并不能从容器中获取其中的每一个值,因为Bloom filter压根就没把元素存储在容器中,而是通过一个散列函数映射成一个值保存在数组中。

二. 可迭代对象(iterable)

大部分对象都是可迭代,只要实现了__iter__方法的对象就是可迭代的。

__iter__方法会返回迭代器(iterator)本身,例如:

>>> lst = [1,2,3]

>>> lst.__iter__()

Python提供一些语句和关键字用于访问可迭代对象的元素,比如for循环、列表解析、逻辑操作符等。

判断一个对象是否是可迭代对象:

>>> from collections import Iterable # 只导入Iterable方法

>>> isinstance('abc', Iterable)

True

>>> isinstance(1, Iterable)

False

>>> isinstance([], Iterable)

True

这里的isinstance()函数用于判断对象类型。

可迭代对象一般都用for循环遍历元素,也就是能用for循环的对象都可称为可迭代对象。

例如,遍历列表:

>>> lst = [1, 2, 3]

>>> for i in lst:

... print i

...

三. 迭代器

迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个Stoplteration异常,以终止迭代(只能往后走不能往前退)

实现了迭代器协议的对象(对象内部定义了一个__iter__()方法)

python中的内部工具(如for循环,sum,min,max函数等)基于迭代器协议访问对象。

使用迭代器的好处:

1)如果使用列表,计算值时会一次获取所有值,那么就会占用更多的内存。而迭代器则是一个接一个计算。

2)使代码更通用、更简单。

判断是否是迭代器:

>>> from collections import Iterator

>>> isinstance(d, Iterator)

False

>>> isinstance(d.iteritems(), Iterator)

True

使用next方法:

>>> iter_items = d.iteritems()

>>> iter_items.next()

('a', 1)

>>> iter_items.next()

('c', 3)

>>> iter_items.next()

('b', 2)

迭代器的原理:

1 #基于迭代器协议

2 li = [1,2,3]

3 diedai_l = li.__iter__()

4 print(diedai_l.__next__())

5 print(diedai_l.__next__())

6 print(diedai_l.__next__())

7 # print(diedai_l.__next__()) # 超出边界报错

8

9 #下标

10 print(li[0])

11 print(li[1])

12 print(li[2])

13 # print(li[3]) # 超出边境报错

14

15 # 用while循环模拟for循环机制

16 diedai_l = li.__iter__()

17 while True:

18 try:

19 print(diedai_l.__next__())

20 except StopIteration:

21 print("迭代完毕,循环终止")

22 break

23

24 # for循环访问方式

25 # for循环本质就是遵循迭代器协议的访问方式,先调用diedai_l=li.__iter__方法

26 # 或者直接diedai_l=iter(l),然后依次执行diedai_l.__next__(),直到捕捉到

27 # StopItearation终止循环

28 # for循环所有的对象的本质都是一样的原理

四. 生成器

可以理解为一种数据类型,自动实现迭代器协议

在调用生成器运行的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行next()方法时从当前位置继续运行

表现形式:

生成器函数 带yield的函数(1、返回值 2、保留函数的运行状态)

next(t)  t.__next__  t.send(可以给上一层的yield传值)

# 用生成器函数

# yield 相当于return控制的是函数的返回值

# x=yield的另外一个特性,接收send传过来的值,赋值给x

def test():

print("开始啦")

first = yield # return 1 first = None

print("第一次",first)

yield 2

print("第二次")

t = test()

print(test().__next__())

res = t.__next__() # next(t)

print(res)

res = t.send("函数停留在first那个位置,我就是给first赋值的")

print(res)

输出结果

开始啦

None

开始啦

None

第一次 函数停留在first那个位置,我就是给first赋值的

生成器表达式

print(sum(i for i in range(10000))) # 表达式一般用for循环 (i for i in range(10000))

# 作用 节省内存,在内部已经实现了__iter__的方法

五. 装饰器

1. 定义

在不修改被修饰函数的源代码和调用方式的情况下给其添加额外功能.

装饰器 = 高阶函数+函数嵌套+闭包

import time #导入时间模块

def foo(func): # func = test

def bar(*args,**kwargs):

start_time = time.time()

res = func(*args,**kwargs) # 这里就是在运行test() 赋予变量

stop_time = time.tiem()

print("一场LOL时间为{}").format(stop_time-start_time)

return res # 返回test()的值

return bar

def test(name, age):

time.sleep(1)

print("哈哈")

return "heihei"

res = test("德玛西亚", age=10)

print(ret)

六. 闭包

根据这句话,其实我们自己就可以总结出在python语言中形成闭包的三个条件,缺一不可:

1)必须有一个内嵌函数(函数里定义的函数)——这对应函数之间的嵌套

2)内嵌函数必须引用一个定义在闭合范围内(外部函数里)的变量——内部函数引用外部变量

3)外部函数必须返回内嵌函数——必须返回那个内部函数

def funx():

x=5

def funy():

nonlocal x

x+=1

return x

return funy

python闭包的优点:

避免使用全局变量

可以提供部分数据的隐藏

可以提供更优雅的面向对象实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/381411.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python类的成员函数_Python为类对象动态添加成员函数

Python: 为对象动态添加函数 , 且函数定义 来自一个 str 在 Python 中 , 通常情况下 , 你只能为对象添加一个已经写好的方法 需求 : 传入一个 str 类型的变量 , 其值是一个完整的合法的 Python 函数定义 , 然后为一个对象添 加这个函数 : method_strudef say(self, name) print…

关于重装系统后或打补丁后不能上网的问题的解决

前些日子,换了新机器,装系统,然后下驱动装一些最基本的软件,如QQ,安全卫士,杀毒软件(俺只用免费的,嘿嘿,如德国的小红伞,一般情况就作够用了)。上…

java对接华为推送服务_华为HMS Core 4.0版本即将来袭:包含新推送服务

据官方消息,在12月27日的HUAWEI Developer Groups(简称HDG)大连活动上,华为消费者云服务HMS运营经理透露HMS Core 4.0版本即将上线,由原来的14项增加至24项核心开放功能,近日即将开放新版本众测,不久之后开发者们将会体…

python xml etree_python解析xml文件之xml.etree.cElementTree和xml.etree.ElementTree区别和基本使用...

1、解析速度:ElementTree在 Python 标准库中有两种实现。一种是纯 Python 实现例如 xml.etree.ElementTree ,另外一种是速度快一点的 xml.etree.cElementTree 。你要记住: 尽量使用 C 语言实现的那种,因为它速度更快,而…

CISSP的成长之路(二十一):用户持有凭证

在51CTO安全频道特别策划的CISSP的成长之路系列的上一篇文章《讲解身份验证过程》里,J0ker给大家介绍了用户验证时所依赖的三种验证要素、密码和密码短语及其安全使用原则。作为技术实施难度和成本最低的用户验证方案,基于密码的用户验证方案广泛应用于我们的日常生…

mysql主从同步面试题_面试被问MySQL 主从复制,怎么破?

注意:此处使用的是新创建的账户。# 4.4 启动主从复制1)启动从库 slave 线程:start slave;2)查看从服务器复制功能状态:show slave status\G;返回结果:*************************** 1. row ***************************Slave_IO_St…

python控制手机自动刷新闻_Python控制android手机实现微信自动跳一跳

学习一个新东西一定要有趣,如果只是简单学习语法太枯燥了。弄了个跳一跳的程序,注释写的很清楚#!/usr/bin/env python # encoding: utf-8 # software: PyCharm # time: 2019/7/10 15:39 # author: Paulson●Wier # file: jump_跳一跳.py # desc: import …

独家:Havok 发布新的 AI 中间件

独家:Havok 发布新的 AI 中间件 March 23rd, 2009 Alex J. Champandard 2009-3-23,赖勇浩(http://blog.csdn.net/lanphaday)译 原文地址:http://aigamedev.com/middleware/havok-ai-announced 在20日(上周五…

mysql查询入门_Mysql入门(四)查询

我们继续查询~条件查询及逻辑运算符条件查询如果我只想查询&#xff0c;年级小于30的&#xff0c;可以加个where条件关键字~条件查询敲黑板select * from yingxiong where y_age<30where 表示条件(条件关键字)&#xff0c;在where之后跟过滤的条件注意&#xff1a;逻辑运算符…

maven provided_Maven 教程之 pom.xml 详解

点击上方“Java知音”&#xff0c;选择“置顶公众号”技术文章第一时间送达&#xff01;作者&#xff1a;dunwuhttps://github.com/dunwu/blog推荐阅读(点击即可跳转阅读)1. SpringBoot内容聚合2. 面试题内容聚合3. 设计模式内容聚合4. Mybatis内容聚合5. 多线程内容聚合简介什…

python将一个列表里面的某类元素取出来_03|Python列表常见操作

欢迎关注pythoner派微信公众号及头条号Python常见的数据结构我们在上一节中已经讲过再阅读文章前&#xff0c;请打开PythonIDE列表&#xff1a;1.定义一个列表现在我们有3瓶不同类型的啤酒&#xff0c;现在我们将其放入列表之中beer [粉象,白熊,橙色炸弹]2.向列表中追加元素现…

使用SDL打造游戏世界之入门篇 - 2

VC6下SDL的安装和初步使用首先&#xff0c;我们为所有的工程创建一个文件夹tutorial,将下载的开发库SDL-devel-1.2.8-VC6.zip拷贝到tutorial下并解压&#xff0c;并保证如下的文件夹层次&#xff08;图2&#xff09;如下&#xff1a;图2下面我们打开Visual Studio6.0&#xff0…

python虚拟环境管理工具_Python虚拟环境和包管理工具Pipenv的使用详解--看完这一篇就够了...

前言Python虚拟环境是一个虚拟化&#xff0c;从电脑独立开辟出来的环境。在这个虚拟环境中&#xff0c;我们可以pip安装各个项目不同的依赖包&#xff0c;从全局中隔离出来&#xff0c;利于管理。 传统的Python虚拟环境有virtualenv&#xff0c;使用pip freeze → requirements…

python中upper函数有什么用_几个有用的python字符串函数(format,join,split,startwith,endwith,lower,upper)...

你需要知道的python字符串函数 format 字符串的format函数为非字符串对象嵌入字符串提供了一种非常强大的方法。在format方法中&#xff0c;字符串使用{}来代替一系列字符串的参数并规定格式。下面通过几个例子来详细解释其用法 直接使用{} apple_num 10 print("I have {…

QA

开发期间测试人员的工作是很多的&#xff0c;首先&#xff0c;要参加评审工作&#xff0c;比如需求评审、概要设计评审、详细设计评审等等&#xff0c;在评审过程中不要只抱着学习的目的&#xff0c;而是要提出有意义的建议&#xff0c;比如在需求评审中要提出一对可测试性需求…

用于连接mysql的java类_【考试】列举Java连接数据库用到的类有哪些。

好吧&#xff0c;说明一下JDBC连接数据库的步骤。创建一个以JDBC连接数据库的程序&#xff0c;包含7个步骤&#xff1a;1、加载JDBC驱动程序&#xff1a;例如&#xff1a;try{//加载MySql的驱动类Class.forName("com.mysql.jdbc.Driver") ;}catch(ClassNotFoundExcep…

水晶报表的统计功能-Crystal Report Sub total Per Page

先大概表述下我对水晶报表的理解&#xff1a; 大体上Crystal Report 可以理解为3部分&#xff1a; 第一部分&#xff1a;数据引擎 Crystal Report 集成了各种数据访问接口&#xff0c;可以方便的从数据仓库中提取数据&#xff0c;并把返回的数据做为一个数据集。 第二部分&…

centos 6.8安装git_RPM包的卸载与安装,包含依赖包卸载

一、 rpm包的管理介绍&#xff1a;一种用于互联网下载包的打包及安装工具&#xff0c;它包含在某些Linux分发版中&#xff0c;它生成具有RPM扩展名的文件&#xff0c;RPM是RedHat Package Manager&#xff08;RedHat软件包管理工具&#xff09;的缩写&#xff0c;类似windows的…

内置系统账户:Local system/Network service/Local Service 区别

LocalSystem 账户   LocalSystem是预设的拥有本机所有权限的本地账户&#xff0c;这个账户跟通常的用户账户没有任何关联&#xff0c;也没有用户名和密码之类的凭证。这个服务账户可以打开注册表的HKEY_LOCAL_MACHINE\Security键&#xff0c;当LocalSystem访问网络资源时&a…

anaconda matplotlib 输出动画_Python+Matplotlib 制作排序算法的动画

1 、算法的魅力深刻研究排序算法是入门算法较为好的一种方法&#xff0c;现在还记得4年前手动实现常见8种排序算法&#xff0c;通过随机生成一些数据&#xff0c;逐个校验代码实现的排序过程是否与预期的一致&#xff0c;越做越有劲&#xff0c;越有劲越想去研究&#xff0c;公…