Python基础之 函数名,闭包,和迭代器
1.函数名作用
函数名本质上就是函数的内存地址或对象。
1.可以被引用
2.可以被当作容器类型的元素
3.可以当作函数的参数和返回值
4.如果记不住的话,那就记住一句话,就当普通变量用
2.闭包
什么叫做闭包?
1.必须是嵌套函数
2.在嵌套函数的内部的函数可以使用外部的变量(非全局变量)
闭包的特性?
1.python中的闭包会出现内存驻留,普通函数执行一次内存开辟的空间就销毁了。(此处记录一下:不是开辟的内存空间销毁了,是命名空间存放的变量名和值的映射关系销毁了,而开辟的空间的值还在!)
2.闭包会出现内存泄漏的问题
3.装饰器的本质就是闭包(面试必问)
闭包的常用场景?
我们知道在函数内的变量在函数外访问的话,直接调用函数返回就好了,那么如果我们想在函数外部来调用内部的函数该怎么做那?
直接在调用函数是返回函数的名字就可以了
闭包的优点:
全局里存放会有污染和不安全的现象,只能内部访问外部,不能外部访问内部,保证数据安全
def wrapper():
money =10
def inner(num):
nonlocal money
money +=num
print(money)
print(inner.__closure__) #不返回none的话就是闭包
return inner
wrapper()(100)
3.迭代器
在以前都听过迭代对象,能被for循环的就是可迭代对象,包括字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的。
那我们要怎样证明那?
上面说,能被for循环的就是“可迭代的”,但是如果正着想,for怎么知道谁是可迭代的呢?
因为他们都遵循了可迭代协议,那什么又是可迭代协议呢?
可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。(可迭代的对象内部必须含有一个__iter__方法,才能叫可迭代对象,也就能得到相应的迭代器)
迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。 那么什么是到底迭代器是什么那?
它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多元素了,则抛出StopIteration异常 查看一个数据类型是否是可迭代的方法:
1.dir(li)
li=[1,2,3]
print(dir(li))
如果里面包含__iter__方法就证明是可迭代对象,遵循可迭代协议
2.
l = [1,2,3]
l_iter = l.__iter__()
from collections import Iterable
from collections import Iterator
print(isinstance(l,Iterable)) #True #查看是不是可迭代对象
print(isinstance(l,Iterator)) #False #查看是不是迭代器 通过"a = 对象.__iter__ # 创建一个迭代器",通过迭代器内部的__next__方法得到下一个迭代器元素,这就是for循环的工作机制! 使用while循环和迭代器来模拟for循环
lst = [6,5,4]
l = lst.__iter__() while True:
try:
i = l.__next__()
print(i)
except StopIteration:
break
注意: 迭代器不能反复,只能向下执行
总结:
Iterable: 可迭代对象. 内部包含__iter__()函数
Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().
迭代器的特点:
1. 节省内存.
2. 惰性机制
3. 不能反复, 只能向下执行.
4.提供一种不依赖索取值的方法,通过__next__()方法取值
缺点:
1.取值不如索引方便
2.惰性机制,用一个取值一个
for循环本质:
for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,
然后使用迭代器协议去实现循环访问,这样所有的对象就都可以通过for循环来遍历了
for循环执行流程
4.递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数(必须有跳出条件)。
举个例子,我们来计算阶乘n! = 1 x 2 x 3 x ... x n,用函数fact(n)表示,可以看出:
fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n
所以,fact(n)可以表示为n x fact(n-1),只有n=1时需要特殊处理。
于是,fact(n)用递归的方式写出来就是:
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
递归函数的优点是定义简单,逻辑清晰。理论上,所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
使用递归函数需要注意防止栈溢出。在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。
由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出。可以试试fact(1000)!
解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归是指,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
总结:
使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。
针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
应用场景:在不知道循环的具体次数的时候使用递归
调整递归最大深度
import sys
sys.setrecursionlimit(10000)
Python基础之 函数名,闭包,和迭代器的更多相关文章
- python全栈 函数名 闭包及迭代器
1,函数名的运用 2.闭包 3.迭代器 一.函数名的运用 1.函数名的命名规范和变量是一样的 函数名其实就是变量名 (1)函数名的内存地址 例: def func(): print("ale ...
- python基础 (函数名,闭包,和迭代器)
1.函数名作用 函数名本质上就是函数的内存地址或对象. 1.可以被引用 2.可以被当作容器类型的元素 3.可以当作函数的参数和返回值 4.如果记不住的话,那就记住一句话,就当普通变量用 2.闭包 什么 ...
- python基础之函数名的使用,闭包以及迭代器
内容梗概: 1. 函数名的使⽤用以及第⼀一类对象 2. 闭包 3. 迭代器 1.函数名一. 函数名的运⽤.函数名是一个变量, 但它是⼀个特殊的变量, 与括号配合可以执行函数的变量.1.1 函数名的内存 ...
- python基础(13):函数名的使用、第一类对象、闭包、迭代器
1. 函数名的运用 函数名是⼀个变量,但它是⼀个特殊的变量,与括号配合可以执⾏函数的变量. 1.1 函数名的内存地址 def func(): print("呵呵") print(f ...
- python之函数名,闭包、迭代器
一.函数名的运用(第一类对象) 函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量. 1,函数名的内存地址: def func(): print("呵呵") pr ...
- python中的函数名,闭包,迭代器
一.函数名 函数名是一个变量,但它是一个特殊的变量,与括号配合可以执行函数的变量,单纯print()出的是一个内存地址. def func(): print('你说你有点难追') print(func ...
- Python基础之函数的闭包与装饰器的介绍
1.闭包的概念: 如果在一个函数中,定义了另外一个函数,并且那个函数使用了外面函数的变量,并且外面那个函数返回了里面这个函数的引用,那么称为里面的这个函数为闭包. 2.话不多说,以demo示例: de ...
- Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器
Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: 1. 可以在局部作用域声明一 ...
- python基础之函数详解
Python基础之函数详解 目录 Python基础之函数详解 一.函数的定义 二.函数的调用 三.函数返回值 四.函数的参数 4.1 位置参数 4.2 关键字参数 实参:位置实参和关键字参数的混合使用 ...
随机推荐
- ubuntu 16.04系统下解决MySQL 5.7版本的root用户重置密码问题
最近在ubuntu系统上安装了MySQL,但是安装时没有提示输入root用户密码,在网上找了一天解决方案,试图修改root用户下的登入密码,但是网上的帖子都不凑效,最后终于改成功了,因此记下来以供有同 ...
- STM32串口空闲中断
串口初始化 #include "usart5.h" vu16 UART5_RX_STA=0; char UART5_RX_BUF[UART5_REC_LEN]; u8 UART5_ ...
- angular 2+ 变化检测系列三(Zone.js在Angular中的应用)
在系列一中,我们提到Zone.js,Zones是一种执行上下文,它允许我们设置钩子函数在我们的异步任务的开始位置和结束位置,Angular正是利用了这一特性从而实现了变更检测. Zones.js非常适 ...
- 关于hbase api的个人总结(带jar包)
1.如果本机代码没问题,jar包没问题的话,检查集群也没用问题,但是代码运行显示 找不到对应的映射主机,需要在 C:\Windows\System32\drivers\etc 中修改host文件, ...
- linux中python3安装和使用
python安装 下载python安装包和依赖环境 #自由选择python3源码包的版本https://www.python.org/ftp/python/https://www.python.org ...
- Android应用程序MVC框架实例分析
问题提出:如何优雅地分离出应用程序的状态.用户交互和数据表现?如何通过框架体现工程的高性能.高灵活性.高响应性? MVC定义:model.view.controller三者的有机组合,分别表示:模型. ...
- python 网络爬虫概念与HTTP(s)协议
1. 爬虫相关概念 1.1 定义 爬虫就是通过编写程序模拟浏览器上网,然后让其去互联网上抓取数据的过程 1.2 主流语言实现爬虫优劣 php:可以实现爬虫.但是php在实现爬虫中支持多线程和多进程方面 ...
- XVII Open Cup named after E.V. Pankratiev. GP of Siberia, Division 1
1. Ski race 枚举枚举倍数判断即可.时间复杂度$O(n\log m)$. #include<cstdio> #include<algorithm> using nam ...
- 做rl_abs过程中遇到的问题
问题一 运行 train_abstractor.py就出现这个问题 nohup: ignoring input start training with the following hyper-para ...
- angular.isArray()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...