函数名的使用以及第一类对象

函数名的运用

函数名是一个变量, 但它是一个特殊的变量, 与括号配合可以执行函数的变量

1.函数名的内存地址

1
2
3
4
def func():   
    print("呵呵")
print(func)
结果: <function func at 0x1101e4ea0>

2. 函数名可以赋值给其他变量

1
2
3
4
5
def func():   
    print("呵呵")
    print(func)
= func    # 把函数当成一个变量赋值给另一个变量
a()     # 函数调用 func()

3. 函数名可以当做容器类的元素

1
2
3
4
5
6
7
8
9
10
11
def func1():   
    print("呵呵")
def func2():   
    print("呵呵")
def func3():   
    print("呵呵")
def func4():  
     print("呵呵")
lst = [func1, func2, func3]
for in lst:  
     i()

4. 函数名可以当做函数的参数

1
2
3
4
5
6
7
def func():   
    print("吃了么")
def func2(fn):   
    print("我是func2")   
    fn()    # 执行传递过来的fn   
    print("我是func2")
func2(func)     # 把函数func当成参数传递给func2的参数fn.

5. 函数名可以作为函数的返回值

1
2
3
4
5
6
7
8
9
def func_1():   
    print("这⾥里里是函数1")   
    def func_2():       
        print("这⾥里里是函数2")   
    print("这⾥里里是函数1")   
    return func_2
fn = func_1()  
# 执行函数1.  函数1返回的是函数2, 这时fn指向的就是上⾯面函数2
fn()    # 执行上面返回的函

闭包

什么是闭包?  闭包就是内层函数, 对外层函数(非全局)的变量的引用. 叫闭包

1
2
3
4
5
6
7
8
def func1():
    name = "alex"
    def func2():
        print(name)
        # 闭包
    func2()
func1()
# 结果: alex

我们可以使用__closure__来检测函数是否是闭包. 使用函数名.__closure__返回cell就是
闭包. 返回None就不是闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
def func1():
    name = "alex"
    def func2():
        print(name)
        # 闭包
    func2()
    print(func2.__closure__)
func1()
 
结果:
alex
(<cell at 0x0000020077EFC378str object at 0x00000200674DC340>,)
返回的结果不是None就是闭包

现在有个问题,这个闭包只能在里边调用啊,外边的怎么调用呢?

1
2
3
4
5
6
7
8
def outer():   
    name = "alex"   
    # 内部函数   
    def inner():       
        print(name)   
    return inner
fn = outer()   # 访问外部函数, 获取到内部函数的函数地址
fn()    # 访问内部函数       

这样就实现了外部访问,那如果多层嵌套呢?很简单,只需要一层一层的往外层返回就行了  

1
2
3
4
5
6
7
def func1():   
    def func2():       
        def func3():       
            print("嘿嘿")      
        return func3 
    return func2
func1()()()       

由它我们可以引出闭包的好处.  由于我们在外界可以访问内部函数. 那这个时候内部函数访问的时间和时机就不一定了, 因为在外部, 我可以选择在任意的时间去访问内部函数. 这 个时候. 想一想. 我们之前说过, 如果一个函数执行完毕. 则这个函数中的变量以及局部命名空间中的内容都将会被销毁.  在闭包中. 如果变量被销毁了. 那内部函数将不能正常执行. 所 以. python规定. 如果你在内部函数中访问了外层函数中的变量. 那么这个变量将不会消亡. 将会常驻在内存中. 也就是说. 使用闭包, 可以保证外层函数中的变量在内存中常驻. 这样做 有什么好处呢? 非常大的好处. 我们来看看下边的代码

1
2
3
4
5
6
7
8
9
10
def func():
    name = 'alex'
     
    def foo():
        print(name)
    return foo
 
msg = func()
 
msg() #这样的话就是将name='alex'存放在一个常驻的内存中,并且外界不能修改

闭包的作用就是让一个变量能够常驻内存,供后面的程序使用  

迭代器

我们之前一直在用可迭代对象进行操作,那么到底什么是可迭代对象.我们现在就来讨论讨论可迭代对象.首先我们先回顾下我们

熟知的可迭代对象有哪些:

str  list   tuple  dic  set  那为什么我们称他们为可迭代对象呢?因为他们都遵循了可迭代协议,那什么又是可迭代协议呢.首先我们先看一段错误的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
对的
= 'abc'
for in s:
    print(i)
 
结果:
a
b
c
 
错的
for in 123:
    print(i)
 
结果
Traceback (most recent call last):
  File "D:/python_object/二分法.py", line 62in <module>
    for in 123:
TypeError: 'int' object is not iterable

  

注意看报错信息,报错信息中有这样一句话: 'int' object is not iterable 翻译过来就是整数类型对象是不可迭代的.

iterable表示可迭代的.表示可迭代协议 那么如何进行验证你的数据类型是否符合可迭代协议.我们可以通过dir函数来查看类中定义好的

所有方法

1
2
3
= 'abc'
print(dir(a))  # dir查看对象的方法和函数
# 在打印结果中寻找__iter__ 如果存在就表示当前的这个类型是个可迭代对象

我们刚刚测了字符串中是存在__iter__的,那我们来看看  列表,元祖,字典.集合中是不是有存在__iter__

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 列表
lst = [1,2]
print(dir(lst))
 
# 元祖
tuple = (1,2)
print(dir(tuple))
 
# 字典
dic = {'a':1,'b':2}
print(dir(dic))
 
# 集合
se = {1,2,3,4,4}
print(dir(se))

是不是发现以上都有__iter__并且还很for循环啊,其实也可以这么说可以for循环的就有__iter__方法,包括range

1
print(dir(range))

这是查看一个对象是否是可迭代对象的第一种方法,我们还可以通过isinstence()函数来查看一个对象是什么类型的

1
2
3
4
5
6
7
8
= [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            #查看是不是迭代器
print(isinstance(l_iter,Iterator)) #True       
print(isinstance(l_iter,Iterable)) #True

通过上边的我们可以确定.如果对象中有__iter__函数,那么我们认为这个对象遵守了可迭代协议.就可以获取到相应的迭代器

.这里的__iter__是帮助我们获取到对象的迭代器.我们使用迭代器中的__next__()来获取到一个迭代器的元素,那么我们之前所讲的

for的工作原理到底是什么? 继续向下看:

1
2
3
4
5
6
7
8
9
10
= "我爱北京天安⻔"
= s.__iter__() # 获取迭代器
print(c.__next__()) # 使⽤迭代器进⾏迭代. 获取⼀个元素 我
print(c.__next__()) # 爱
print(c.__next__()) # 北
print(c.__next__()) # 京
print(c.__next__()) # 天
print(c.__next__()) # 安
print(c.__next__()) # ⻔
print(c.__next__()) # StopIteration

for循环是不是也可以,并且还不报错啊,其实上边就是for的机制,

我们使用while循环和迭代器来模拟for循环: 必须要会

1
2
3
4
5
6
7
8
9
lst = [6,5,4]
= lst.__iter__()
 
while True:
    try:
        = l.__next__()
        print(i)
    except StopIteration:
        break

注意: 迭代器不能反复,只能向下执行

总结:

Iterable: 可迭代对象. 内部包含__iter__()函数

Iterator: 迭代器. 内部包含__iter__() 同时包含__next__().

迭代器的特点:

1. 节省内存.

2. 惰性机制

3. 不能反复, 只能向下执行.

我们可以把要迭代的内容当成子弹. 然后呢. 获取到迭代器__iter__(), 就把子弹都装在弹夹中.  然后发射就是__next__()把每一个子弹(元素)打出来. 也就是说, for循环的时候.一开始的 时候是__iter__()来获取迭代器. 后面每次获取元素都是通过__next__()来完成的. 当程序遇到 StopIteration将结束循环.

python 小兵(7)迭代器的更多相关文章

  1. Python基础之迭代器和生成器

    阅读目录 楔子 python中的for循环 可迭代协议 迭代器协议 为什么要有for循环 初识生成器 生成器函数 列表推导式和生成器表达式 本章小结 生成器相关的面试题 返回顶部 楔子 假如我现在有一 ...

  2. python is、==区别;with;gil;python中tuple和list的区别;Python 中的迭代器、生成器、装饰器

    1. is 比较的是两个实例对象是不是完全相同,它们是不是同一个对象,占用的内存地址是否相同 == 比较的是两个对象的内容是否相等 2. with语句时用于对try except finally 的优 ...

  3. python基础之迭代器协议和生成器

    迭代器和生成器补充:http://www.cnblogs.com/luchuangao/p/6847081.html 一 递归和迭代 略 二 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个ne ...

  4. python设计模式之迭代器与生成器详解(五)

    前言 迭代器是设计模式中的一种行为模式,它提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示.python提倡使用生成器,生成器也是迭代器的一种. 系列文章 python设计模 ...

  5. Python之路迭代器协议、for循环机制、三元运算、列表解析式、生成器

    Python之路迭代器协议.for循环机制.三元运算.列表解析式.生成器 一.迭代器协议 a迭代的含义 迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的 ...

  6. python基础8 -----迭代器和生成器

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

  7. Python 拓展之迭代器

    写在之前 今天来讲讲「迭代器」的内容,其实已经拖了好多天了,感觉再不写就要忘记了.「迭代」相信对你来说已经不陌生了,我前面曾经专门用一篇文章来讲,如果你已经没有什么印象的话,就再点进去看看(零基础学习 ...

  8. 【Python基础】迭代器、生成器

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

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

    目录 Python - 三大器 迭代器,生层器,装饰器 一. 容器 二. 可迭代对象(iterable) 三. 迭代器 四. 生成器 五. 装饰器 1. 定义 六. 闭包 Python - 三大器 迭 ...

随机推荐

  1. codeforc 603-A. Alternative Thinking(规律)

    A. Alternative Thinking time limit per test 2 seconds memory limit per test 256 megabytes   Kevin ha ...

  2. anaconda安装PIL

    PIL仅支持到python2.7: Pillow支持Python 3.x: conda install pillow 参考文献: 使用anaconda安装python3版本的PIL_不行不至-CSDN ...

  3. Spring MVC 文件上传、Restful、表单校验框架

    目录 文件上传 Restful Restful 简介 Rest 行为常用约定方式 Restful开发入门 表单校验框架 表单校验框架介绍 快速入门 多规则校验 嵌套校验 分组校验 综合案例 实用校验范 ...

  4. What Makes for Good Views for Contrastive Learning

    目录 概 前 InfoMin Sweet Spot 空间距离 Color Spaces Frequency Separation 构建 novel views 无监督 半监督 Tian Y., Sun ...

  5. javascript实现base64格式转码与解码

    最近碰到一个需求,后端返回base64格式的数据,前端需要进行base64格式解码,好了,前端采用内部提供的atob函数进行解码,开完成,交付测试,然后测试小哥哥小姐姐反馈说中文乱码! 然后查了一下, ...

  6. CSS基础 华为渐变色产品列表 综合实战

    华为网页链接:https://www.huawei.com/cn/?ic_medium=direct&ic_source=surlent html代码部分: <div class=&qu ...

  7. MYSQL实现上一条下一条功能

    select id from(select *, (@i:=@i+1) as rownum from pre_bet_zhibo,(select @i:=0) as itwhere link_cone ...

  8. android studio 获取 SHA1 值

    1. 生成密钥文件 2.找到控制台 输入指令 cd c: cd C:\Users\[当前登录的用户文件夹]\.android 如 cd C:\Users\cenxi\.android 就是这里 然后输 ...

  9. dispatcher-servlet.xml文件配置模板

    完整代码如下: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http:/ ...

  10. python驱动SAP完成数据导出(一)

    写在前面 我们使用Python驱动SAP时,经常会需要导出一些SAP报表数据至本地Excel文件.这个看似简单的问题背后,其实暗藏玄机,今天小爬就带各位同学好好捋捋. 以事务代码FB03(凭证清单)为 ...