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‘))

三、可迭代对象
for i in ‘abc‘:
  print(i)

for i in 123:
  print(i)     # ‘int‘ object is not iterable表示不是可迭代对象

对象内部含有__iter__方法就是可迭代对象.
可迭代对象满足可迭代协议。

可迭代对象:str list dict,tuple,set,range()
dir() :返回一个列表,列表里面包含了传入的参数的属性、方法

s1 = ‘strs‘

print(dir(s1))

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

# 第一个方法
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、可迭代对象与迭代器的区别:
1,可迭代对象不能取值,迭代器是可以取值的。
(我们知道字典列表都是可迭代对象,为什么它们能取值呢?这是因为为了方便我们操作,我们设定了
索引(键)用来操作字典列表取值,如果没有人为为它们设置的索引(键),它们是不能取值的)
2, 迭代器非常节省内存。
3,迭代器每次只会取一个值。
4,迭代器单向的,一条路走到头。

3、可迭代对象 --->(转化成)迭代器

lis = [1, 2, 3]  # 可迭代对象
ite1 = lis.__iter__()  # 迭代器  <list_iterator object at 0x0000027A183BFFD0>
ite1 = iter(lis)  # 迭代器  <list_iterator object at 0x0000027A183BFFD0>
print(ite1)

4、迭代器如何取值? next一次,取一个值

print(ite1.__next__())
print(ite1.__next__())
print(ite1.__next__())

5、while循环模拟for循环机制
1,将可迭代对象转化成迭代器。
2,调用__next__方法取值。
3,利用异常处理停止报错。

s1 = ‘abcdefg‘
iter1 = s1.__iter__()
while 1:
    try:
        print(iter1.__next__())
    except StopIteration:
        break

原文地址:https://www.cnblogs.com/yidashi110/p/10092280.html

时间: 2024-08-25 18:49:14

python之函数闭包、可迭代对象和迭代器的相关文章

11.Python初窥门径(函数名,可迭代对象,迭代器)

Python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return l print(func(1)) # [1] print(func(2)) # [1,2] print(func(3)) # [1,2,3] 二.函数名的应用 函数名指向的是函数的内存地址,加上()就执行这个函数 def func(args): return args print(func) #

搞懂python中的可迭代对象和迭代器对象(即迭代器)

可迭代的对象和迭代器解惑: 可迭代的对象:常见的可以被for循环迭代的一些数据类型都是可迭代的对象,如列表,元组,字典,集合,字符串,生成器,range函数生成的数列等,从广泛的意义上来说,这些对象都有一个内置的iter方法,且该方法可以返回一个迭代器对象,当用iter(可迭代对象)调用这个对象时,会返回一个迭代器对象(属于Iterator类) for语句的原理就是先用iter函数获取可迭代对象的迭代器,然后调用next函数,此函数自动调用迭代器对象的next方法,每次遍历都返回相应的值,如果没

Python 函数名,可迭代对象及迭代器

函数名是什么?1,函数名就是函数的内存地址a = 2b = ac = bprint(c)2,函数名可以作为变量.def func1(): print(666)f1 = func1()f2 = f1print(f2)3,函数名可以作为函数的参数.def func1(): print(666)def func2(x): print(x) x()print(func1)函数名可以当做函数的返回值.def wapper(): def inner(): print('inner') return inne

第八章 Python可迭代对象、迭代器和生成器

8.1 可迭代对象(Iterable) 大部分对象都是可迭代,只要实现了__iter__方法的对象就是可迭代的. __iter__方法会返回迭代器(iterator)本身,例如: >>> lst = [1,2,3] >>> lst.__iter__() <listiterator object at 0x7f97c549aa50> Python提供一些语句和关键字用于访问可迭代对象的元素,比如for循环.列表解析.逻辑操作符等. 判断一个对象是否是可迭代对象

what&#39;s the python之可迭代对象、迭代器与生成器(附面试题)

可迭代对象 字符串.列表.元祖.集合.字典都是可迭代的,数字是不可迭代的.(可以用for循环遍历取出内部元素的就是可迭代的) 如何查看一个变量是否为可迭代: from collections import Iterable l = [1,2,3,4] t = (1,2,3,4) d = {1:2,3:4} s = {1,2,3,4} print(isinstance(l,Iterable)) print(isinstance(t,Iterable)) print(isinstance(d,Ite

5.1.24 Python之列表生成式、生成器、可迭代对象与迭代器

语法糖的概念 列表生成式 生成器(Generator) 可迭代对象(Iterable) 迭代器(Iterator) Iterable.Iterator与Generator之间的关系 一.语法糖的概念 "语法糖",从字面上看应该是一种语法."糖",可以理解为简单.简洁.其实我们也已经意识到,没有这些被称为"语法糖"的语法,我们也能实现相应的功能,而 "语法糖"使我们可以更加简洁.快速的实现这些功能. 只是Python解释器会把这

完全理解 Python 迭代对象、迭代器、生成器

2017/05/29 · 基础知识 · 9 评论 · 可迭代对象, 生成器, 迭代器 原文出处: liuzhijun 本文源自RQ作者的一篇博文,原文是Iterables vs. Iterators vs. Generators,俺写的这篇文章是按照自己的理解做的参考翻译,算不上是原文的中译版本,推荐阅读原文,谢谢网友指正. 在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式

解决python疑难杂症—什么是迭代协议、迭代对象和迭代器?

什么是迭代协议 只要某个类型(类)定义了iter()和next()方法就表示支持迭代协议. iter()需要返回一个可迭代对象.只要定义了iter()就表示能够通过for/in/map/zip等迭代工具进行对应的迭代,也可以手动去执行迭代操作. 1 for x in Iterator 2 X in Iterator 同时,可迭代对象还可以作为某些函数参数,例如将可迭代对象构建成一个列表list(Iterator)来查看这个可迭代对象会返回哪些数据: L = list(Iterator) 需要注意

Python中的可迭代对象与迭代器对象

刚刚学习Python,对“可迭代对象”和"迭代器对象"的个人理解,不知道对不对. 1.几个概念 1.迭代工具:包括for循环.列表解析.in成员关系测试.....等等在内的,用于依次访问可迭代对象(容器)内元素的操作(?). 2.迭代器对象:具有__next__()方法的对象.该方法能够自动返回下一个结果,当到达序列结尾时,引发StopIteration异常. 3.可迭代对象:具有__iter__()方法的对象.该方法可获取其迭代器对象. 2.迭代过程(以for循环为例) for循环开