python之函数闭包、可迭代对象和迭代器
一、函数名的应用
# 1,函数名就是函数的内存地址,而函数名()则是运行这个函数。
def func():
return print(func) # 返回一个地址 # 2,函数名可以作为变量。
def func1():
print(666) f1 = func1
f2 = f1
f2() # 就等于func1() 此时执行函数 # 3,函数名可以作为函数的参数。
def func1():
print(666) def func2(x):
x() func2(func1) # 输出666 func1作为实参传进func2中,此时在func2中x()等于func1() # 4,函数名可以当做函数的返回值。
def wraaper():
def inner():
print(666)
return inner ret = wraaper() # 执行函数wraaper(),得到返回值inner赋值给ret,这个inner是函数名
ret() # 输出666,ret()等于inner()
# (注意:这里要调用inner()只能是用ret(),因为inner()是wraaper()的嵌套函数,在全局命名空间中并没有声明,所以直接用inner()不能执行,) def func2():
print('in func2') def func3(x):
print('in func3')
return x f = func3(func2) # 给func3传进一个参数func2,返回func2赋值给f
f() # f()等于func2() # 5,函数名可以作为容器类类型的元素。
def f1():
print('f1') def f2():
print('f2') def f3():
print('f3') l = [f1, f2, f3]
d = {'f1': f1, 'f2': f2, 'f3': f3}
# 调用
l[0]() # 输出 f1
d['f2']() # 输出 f2 def func1():
print('in func1') def func2():
print('in func2') def func3():
print('in func3') def func4():
print('in func4') l1 = [func1,func2,func3,func4] #调用
for i in l1:
i() # 像上面的函数名这种,称为第一类对象。
# 第一类对象(first-class object)指:
# 1.可在运行期创建
# 2.可用作函数参数或返回值
# 3.可存入变量的实体。
# (如果不明白,那就记住一句话,就当普通变量用)
6、globals() locals()
globals() #返回全局变量(包含内置函数)的一个字典。
locals() #返回当前位置的变量的字典。
例如:
def func1():
a = 2
b = 3
print(globals()) # 此时globals()在局部命名空间中,但也是返回全局命名空间的一个字典
print(locals()) # 此时locals()在局部命名空间中,所以返回的是局部命名空间的一个字典{'b': 3, 'a': 2} print(globals()) # 此时globals()在全局命名空间中,返回全局命名空间的一个字典
print(locals()) # 此时locals()在全局命名空间中,所以返回的是全局命名空间的一个字典
func1() # 结果: # {'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...} # {'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...} # {'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...} # {'b': 3, 'a': 2}
总结:
globals()无论在哪个命名空间,返回的都是全局命名空间的一个字典
locals()在哪个命名空间就返回哪个命名空间的字典
def func1():
a = 2
b = 3
def inner():
c = 5
d = 6
print(globals()) #{'__name__': '__main__', '__doc__': None(后面还有一大推东西,省略)...}
print(locals()) #{'c': 5, 'd': 6}
inner()
func1()
二、闭包
1、内层函数引用外层函数的变量(非全局变量),这样该内部函数称就称为闭包函数。
(我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?
就把这个函数的名字返回就好了,这是闭包函数最常用的用法)
def wraaper():
name = '鬼见愁'
def inner():
print(name)
return inner f = wraaper()
f()
2、判断闭包函数的方法__closure__
# 1,是闭包返回值会有cell元素
def wraaper():
name = '鬼见愁'
def inner():
print(name)
print(inner.__closure__)
return inner
f = wraaper()
f() # 2,不是闭包就会返回None
name = '鬼见愁'
def wraaper():
def inner():
print(name)
print(inner.__closure__) # None
return inner
f = wraaper()
f() name = '番薯'
def wraaper(n):
n = '番薯'
def inner():
print(n)
print(inner.__closure__) # cell at 0x000002AD93BF76D8
inner()
return inner
wraaper(name)
'''
闭包作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,局部名称空间,
如果这个函数内部形成了闭包,
那么它就不会随着函数的结束而消失。
'''
什么时候用到闭包?
例如:爬虫,装饰器等
下面是一个爬虫的小案例:
from urllib.request import urlopen
def index():
url = "http://www.xiaohua100.cn/index.html"
def get():
return urlopen(url).read()
return get xiaohua = index() # get
content = xiaohua() # get()
print(content.decode('utf-8'))
三、可迭代对象
可迭代的对象(数据类型)如下: 在python中,但凡带内置有__iter__()方法的数据类型(或者对象),都是可迭代的对象
1.列表类型
2.元组类型
3.集合类型
4.字典类型
5.文本类型(文本类型本身就是迭代器对象"具有__next__()"方法)
不可迭代的对象(数据类型)如下:
1.整数类型
2.浮点数类型
for i in 'abc':
print(i) for i in 123:
print(i) # 'int' object is not iterable,表示不是可迭代对象 # dir():返回一个列表,列表里面包含了传入的参数的属性、方法
dir('abc') # ['__add__', '__class__', '__contains__', '__iter__', __str__' ...]
判断一个对象是否是可迭代对象:
# 第一个方法
s1 = 'abc'
dic = {'name':'xiaoming'}
print('__iter__' in dir(s1))
print('__iter__' in dir(dic)) # 第二种方法
from collections import Iterable # 判断是否为可迭代对象
from collections import Iterator # 判断是否为迭代器 print(isinstance('xiaoming',Iterable)) # True
print(isinstance('xiaoming',Iterator)) # False print(isinstance('xiaoming',str)) # True
#isinstance() 应用比type()更广泛,isinstance()不仅可以判断你是不是可迭代对象,
#也可判断你是否迭代器,还可以判断你是什么类型的数据等等,而#type()只能判断你是什么数据类型
四、迭代器
1、对象内部含有__iter__方法且含有__next__方法就是迭代器
#文件句柄是迭代器:
f = open('register', encoding='utf-8')
print('__iter__' in dir(f)) #True
print('__next__' in dir(f)) #True #字典是可迭代对象,不是迭代器。
print('__iter__' in dir(dict)) #True
print('__next__' in dir(dict)) #False
2、可迭代对象与迭代器的区别:
- 可迭代对象的取值依赖索引
- 迭代器提供了一种不依赖索引取值的方式
- 迭代器非常节省内存
- 迭代器每次只会取一个值
- 迭代器单向的,一条路走到头
- 迭代器一定是可迭代对象,反之却不一定
3、可迭代对象如何转化成迭代器
可以使用函数 iter() 或者 __iter__() 获取相应的迭代器
lis = [1, 2, 3] # 可迭代对象
ite1 = lis.__iter__() # 迭代器 <list_iterator object at 0x0000027A183BFFD0>
ite1 = iter(lis) # 迭代器 <list_iterator object at 0x0000027A183BFFD0>
print(ite1)
4、迭代器如何取值?
使用next() 或者 __next__() ,每使用一次next 取一个值
print(ite1.__next__())
print(ite1.__next__())
print(next(ite1))
5、while循环模拟for循环机制
1,将可迭代对象转化成迭代器。
2,调用__next__方法取值。
3,利用异常处理停止报错。
s1 = 'abcdefg'
iter1 = s1.__iter__()
while 1:
try:
print(iter1.__next__())
except StopIteration:
break
python之函数闭包、可迭代对象和迭代器的更多相关文章
- 11.Python初窥门径(函数名,可迭代对象,迭代器)
Python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return ...
- python函数之可迭代对象、迭代器的判断
怎么判断一个对象是可迭代对象还是迭代器 例子 from collections import Iterable, Iterator lst = ['Today is Wednesday', 'Tomo ...
- Python - 分支循环、可迭代对象与迭代器
- python 迭代器(一):迭代器基础(一) 语言内部使用 iter(...) 内置函数处理可迭代对象的方式
简介 在 Python 中,所有集合都可以迭代.在 Python 语言内部,迭代器用于支持: 1.for 循环2.构建和扩展集合类型3.逐行遍历文本文件4.列表推导.字典推导和集合推导5.元组拆包6. ...
- python迭代-如何使用生成器函数实现可迭代对象
如何使用生成器函数实现可迭代对象 问题举例: 实现一个可迭代对象的类,它能迭代出给定范围内 的所有素数: pn = PrimeNumbers(1, 30) for x in pn: print(x) ...
- Python可迭代对象、迭代器和生成器
Python可迭代对象.迭代器和生成器 python 函数 表达式 序列 count utf-8 云栖征文 python可迭代对象 python迭代器 python生成器 摘要: 8.1 可迭代对象( ...
- Python之列表生成式、生成器、可迭代对象与迭代器
本节内容 语法糖的概念 列表生成式 生成器(Generator) 可迭代对象(Iterable) 迭代器(Iterator) Iterable.Iterator与Generator之间的关系 一.语法 ...
- 完全理解Python迭代对象、迭代器、生成器
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
- python可迭代对象和迭代器和生成器
可迭代对象 刚开始我认为这两者是等同的,但后来发现并不是这样:下面直接抛出结论: )可迭代对象包含迭代器. )如果一个对象拥有__iter__方法,其是可迭代对象:如果一个对象拥有next方法,其是迭 ...
随机推荐
- ES6 Module export与import复合使用
export与import复合使用 基本语法 export {...} from '文件'; 等价于 import {...} from "文件": export {...} 先加 ...
- JavaScript(转载自 计科学院 慕课网)
什么是脚本语言? ①脚本语言介于HTML和C,C++,Java,C#等编程语言之间 ②脚本语言与编程语言有相似地方,其函数与编程语言类似,也有变量.与编程语言之间最大的区别是编程语言的语法和规则更为严 ...
- #WEB安全基础 : HTML/CSS | 0x8CSS进阶
你以为自己学这么点CSS就厉害了? 学点新东西吧,让你的网页更漂亮 我们只需要用到图片和网页 这是index.html的代码 <html> <head> <title ...
- Dynamics 365检查工作流、SDK插件步骤是否选中运行成功后自动删除系统作业记录
本人微信公众号:微软动态CRM专家罗勇 ,回复298或者20190120可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . 系统 ...
- 转摘app-稳定性测试
稳定性测试的概念有2种, 一, 稳定性测试,对应于异常性测试,即发生异常情况时,系统如何反应的测试.包含: 1 交互性测试,被打扰的情况,如来电,短信,低电量等.这些其实在上章的功能测试中有提到. 2 ...
- PJSUA2开发文档--第十一章 网络问题
11 网络问题 11.1 IP地址更改 请参阅wiki 处理IP地址更改.请注意,本指南使用PJSUA API作为参考. 11.2 被阻止/过滤的网络 请参阅维基百科 通过阻止或过滤的VoIP网络
- IOS判断NSArray是否为空
场景描述:判断一个集合是否为空,如果不为空执行A,如果为空执行B Java实现方法 public void exec(){ List<String> list = this.getCont ...
- SQLServer之创建嵌套触发器
嵌套触发器创建规则 当触发器执行启动其他触发器的操作时,DML 和 DDL 触发器都是嵌套触发器. 这些操作都可以启动其他触发器等. DML 触发器和 DDL 触发器最多可以嵌套 32 层. 可以通过 ...
- OpenGL实例:三角形
OpenGL实例:三角形 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请查看:计算机图形学 1. 三角形的旋转 #include <GL/ ...
- #020PAT 没整明白的题L1-009 N个数求和 (20 分)
后面的测试点过不去,两个错误一个超时. 目前未解决 L1-009 N个数求和 (20 分) 本题的要求很简单,就是求N个数字的和.麻烦的是,这些数字是以有理数分子/分母的形式给出的,你输出的和 ...