python函数名的运用,闭包,迭代器
一.函数名的运用
函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量.
1.函数名的内存地址
1 def func(): 2 print("呵呵") 3 print(func) 4 结果: 5 function func at 0x1101e4e
2.函数名可以赋值给其他变量
1 def func(): 2 print("呵呵") 3 print(func) 4 a = func # 把函数当成一个变量赋值给另一个变量 5 a() # 函数调用 func()
3.函数名可以当做容器类的元素
1 def func1(): 2 print("呵呵") 3 def func2(): 4 print("呵呵") 5 def func3(): 6 print("呵呵") 7 def func4(): 8 print("呵呵") 9 lst = [func1, func2, func3] 10 for i in lst: 11 i()
4.函数名可以当做函数的参数
1 def func(): 2 print("吃了么") 3 def func2(fn): 4 print("我是func2") 5 fn() # 执行传递过来的fn 6 print("我是func2") 7 func2(func) # 把函数func当成参数传递给func2的参数.
5.函数名可以作为函数的返回值
1 def func_1(): 2 print("这里是函数1") 3 def func_2(): 4 print("这里是函数2") 5 print("这里是函数1") 6 return func_2 7 fn = func_1() # 执行函数1. 函数1返回的是函数2, 这时fn指向的就是上面函数2 8 fn() # 执行上面返回的函数
二.闭包
什么是闭包?闭包就是内层函数,对外层函数(非全局)的变量的引用.叫闭包
1 def func1(): 2 name = "alex" 3 def func2(): 4 print(name) # 闭包 5 func2() 6 func1() 7 结果: 8 alex
我们可以使用__closure__来检测函数是否是闭包.使用函数名.__closure__返回cell就是闭包.返回None就不是闭包.
1 def func1(): 2 name = "alex" 3 def func2(): 4 print(name) # 闭包 5 func2() 6 print(func2.__closure__) # (<cell at 0x10c2e20a8: str object at 7 #0x10c3fc650>,) 8 func1()
问题,如何在函数外边调用内部函数呢?
1 def outer(): 2 name = "alex" 3 # 内部函数 4 def inner(): 5 print(name) 6 return inner 7 8 fn = outer() # 访问外部函数, 获取到内部函数的函数地址 9 fn() # 访问内部函数
那如果多层嵌套呢?很简单,只需要一层一层的往外层返回就行了
1 def func1(): 2 def func2(): 3 def func3(): 4 print("嘿嘿") 5 return func3 6 return func2 7 8 func1()()()
由它我们可以引出闭包的好处.由于我们在外界可以访问内部函数,那这个时候内部函数访问的时间和时机就不一定了,因为在外部,我可以选择在任意时间去访问内部函数.这个时候,想一想,我们之前说过,如果一个函数执行完毕.则这个函数中的变量以及局部命名空间中的内容都会被销毁.在闭包中,如果变量被销毁了,那内部函数将不能正常执行.所以,python规定.如果你在内部函数中访问了外层函数中的变量.那么这个变量将不会消亡.将会常驻在内存中,也就是说.使用闭包,可以保证外层函数中的变量在内存中常驻.这样做有什么好处呢?非常大的好处.我们来看一个爬虫代码:
1 from urllib.request import urlopen 2 def but(): 3 content =urlopen("http://www.xiaohua100.cn/index.html").read() 4 def get_content(): 5 return content 6 return get_conte 7 fn = but() # 这个时候就开始加载校花100的内容 8 # 后面需要用到这里面的内容就不需要在执行非常耗时的网络连接操作了 9 content = fn() # 获取内容 10 print(content) 11 content2 = fn() # 重新获取内容 12 print(content2)
综上,闭包的作用就是让变量能够常驻内存.供后面的程序使用
三.迭代器
什么叫做迭代器?迭代器英文意思是iterator。
1 l = [1,2,3,4] 2 l_iter = l.__iter__() # 将可迭代的转化成迭代器 3 item = l_iter.__next__() 4 print(item) 5 item = l_iter.__next__() 6 print(item) 7 item = l_iter.__next__() 8 print(item) 9 item = l_iter.__next__() 10 print(item) 11 item = l_iter.__next__() 12 print(item)
迭代器遵循迭代器协议:必须拥有__iter__方法和__next__方法。
for循环,能遍历一个可迭代对象,他的内部到底进行了什么?
- 将可迭代对象转化成迭代器。(可迭代对象.__iter__())
- 内部使用__next__方法,一个一个取值。
- 加了异常处理功能,取值到底后自动停止。
用while循环模拟for循环:
1 l = [1,2,3,4] 2 l_iter = l.__iter__() 3 while True: 4 try: 5 item = l_iter.__next__() 6 print(item) 7 except StopIteration: 8 break
为什么要有for循环?
基于上面讲的列表这一大堆遍历方式,聪明的你立马看除了端倪,于是你不知死活大声喊道,你这不逗我玩呢么,有了下标的访问方式,我可以这样遍历一个列表啊
1 =[1,2,3] 2 3 index=0 4 while index < len(l): 5 print(l[index]) 6 index+=1 7 8 #要毛线for循环,要毛线可迭代,要毛线迭代器
没错,序列类型字符串,列表,元组都有下标,你用上述的方式访问,perfect!但是你可曾想过非序列类型像字典,集合,文件对象的感受,所以嘛,年轻人,for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环来遍历了,而且你看到的效果也确实如此,这就是无所不能的for循环,最重要的一点,转化成迭代器,在循环时,同一时刻在内存中只出现一条数据,极大限度的节省了内存~
四.总结
Iterable:可迭代对象.内部包含__iter__()函数
Iterator:迭代器.内部包含__iter__()同时包含__next__().
迭代器的特点:
1.节省内存.
2.惰性机制
3.不能反复,只能向下执行.
我们可以把要迭代的内容当成子弹.然后呢,获取到迭代器__iter__(),就把子弹都装在弹夹中.然后发射就是__next__()把每一个子弹(元素)打出来.也就是说,for循环的时候,一开始的时候是__iter__()来获取迭代器.后面每次获取的元素都是通过__next__()来完成的.当程序遇到StopIteration将结束循环.
转载于:https://www.cnblogs.com/129TL/p/9456624.html
python函数名的运用,闭包,迭代器相关推荐
- python 函数可以作为容器对象的元素_11.Python初窥门径(函数名,可迭代对象,迭代器)...
python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return ...
- python函数名的应用、闭包和迭代器
一.函数名的应用(第一类对象) 函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数变量. 1.函数名的内存地址 def func():print("哈哈") print ...
- python函数闭包的应用_python学习第10天----函数名应用、闭包、迭代器
1.函数名的应用 1)如果直接打印函数名,打印出的为函数的地址 deffunc():print("你好,世界")print(func) 输出: View Code #可将函数赋值给 ...
- python函数名第一类方法、f-string格式化、迭代器及递归函数
函数第一类方法 函数名可以赋值给其他变量 def func():print(1) a = func a() # 结果:1 函数名可以当做容器类的元素 def func1():print(1) def ...
- python函数名的语法_Python 基础语法六 ——函数
一个程序可以按不同的功能实现拆分成不同的模块,而函数就是能实现某一部分功能的代码块. 1.函数的概述 定义:在Python中,定义个函数要使用 def 语句,一次写出函数名.括号.括号中的参数和冒号( ...
- python函数名与变量名可以一样吗_python--第一类对象,函数名,变量名
一 . 第一类对象 函数对象可以像变量一样进行赋值 , 还可以作为列表的元素进行使用 可以作为返回值返回 , 可以作为参数进行传递 def func(): def people(): print('金 ...
- 8月30日学习内容整理:命名空间,作用域,函数名本质,闭包
补充: 三元运算:c= a if a>b else b 相当于: if a>b: c=a else: c=b 结构; if条件成立的结果 if 条件 else if条件不成 ...
- Python 函数基础与进阶 闭包 聚合与打散
阅读目录 函数基础 基础知识 return 返回值 不可变类型和可变类型的值传递问题 函数的参数 打散和聚合 函数进阶 函数的注释 命名空间 作用域和全局变量 函数的嵌套和作用域链 函数名 闭包 函数 ...
- Python函数名的本质,你有了解过嘛?
函数名实质上就是函数的内存地址 def wrapper():passprint(wrapper) 1.引用是什么? 当我们定义a=1的时候,系统会开辟一块内存空间来保存1,然后用a变量名保存1所在的内 ...
最新文章
- AI顶会组团“改版”:NeurIPS DDL推迟3周,ICLR连赞助商都要开视频,CVPR还在死撑...
- Dockerfile多阶段构建
- JavaScript实现十种经典排序算法(js排序算法)
- 成功解决TypeError: a bytes-like object is required, not 'str'
- Elasticsearch 字段数据类型
- .NET Core + Kubernetes:Deployment
- cmake安装配置及入门指南
- rtk采点后如何导入cad_ZEMAX:如何导入CAD物体
- PS2: 这篇文章中的图片绘图工具使用的是Dia (sudo apt-get install dia)。据说yEd也很不错。...
- POJ1579 HDU1331 HDU1579 ZOJ1168 Function Run Fun【记忆化递归】
- matlab中单位格式,[转载]matlab中的数据显示格式-format
- V-Rep机器人仿真软件模型导入部分
- 归并算法Java实现
- js图片添加文字水印并设置水印居中的方法
- Python开发游戏自动化后台脚本
- 创建AWS VPC Peering
- AlibabaCloud
- 老客户营销新招 如何拯救店铺复购率
- 11届蓝桥杯单片机设计与开发决赛
- 2023年的 苹果iPhone15/Pro 将有哪些变化
热门文章
- 使用cmake重写live555工程-附源码和视频教程
- FFmpeg入门之常用命令
- PDGAN: A Novel Poisoning Defense Method in Federated Learning Using Generative Adversarial Network笔记
- 【转】反病毒攻防研究第003篇:添加节区实现代码的植入
- 关于多层html标签嵌套引起CSS冲突问题的解决。
- 探究Java常量本质及三种常量池(JVM)
- 调用startActivityForResult后,onActivityResult立刻回调
- android创建avd,详解如何创建和使用AVD
- 【译】Look-ahead Staking in Qtum - What does that even mean?
- 如何使用区块链技术进行项目开发