Python函数名本质,迭代器,迭代对象,闭包

函数名的本质

1 函数名就是内存地址

1 def func():
2     print(666)
3 print(func)   # <function func at 0x0000024E020AB950>

2 函数名可以作为变量

首先,我们先对一个变量进行赋值操作,最终得到c的结果
1 a = 2
2 b = a
3 c = b
4 print(c)    # 2
同样,对函数名进行赋值操作,看能得到什么结果?
1 def func1():
2     print(666)
3 f1 = func1
4 f2 = f1
5 print(f1)   # <function func1 at 0x00000253AA14B950>
6 f1()        # 666
7 f2()        # 666
从上面的结果可知,f1,f2得到的是函数函数名,打印出来的是函数名的地址,而f1(),f2()是函数的内容,也就是函数func1()

3 函数名可以作为函数的参数

1 def func():
2     print(666)
3 def func1():
4     func()
5 def func2(x):
6     x()
7 func2(func1)   # 666

4 函数名可以当作函数的返回值

1 def wraaper():
2     def inner():
3         print('inner')
4     return inner
5 ret = wraaper()    # 将inner函数的地址赋给wraaper()
6 print(ret)   # <function wraaper.<locals>.inner at 0x000002BFFD88B9D8>
7 ret()        # inner
1 def func2():
2     print('in func2')
3 
4 def func3(x):
5     print('in func3')
6     return x
7 
8 f1 = func3(func2)    # in func3   # func2
9 f1()       # func2()  in func2

4 函数名可以作为容器类类型的元素

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()
上面介绍的函数,属于第一类对象

globals() locals()

 globals() # 返回全局变量的一个字典
locals() # 返回 当前位置 的局部变量的字典
 1 def func1():
 2     a = 2
 3     b = 3
 4     print(globals())
 5     print(locals())
 6     def inner():
 7         c = 5
 8         d = 6
 9         print(globals())
10         print(locals())
11     inner()
12 print(locals())
13 print(globals())
14 func1()

闭包

什么是闭包?内层函数对外层函数的变量(非全局变量)的引用并返回,这样就形成了闭包。

通过下面的例子对比闭包与非闭包的区别:

1 # 闭包
2 def wraaper():
3     name = 'alex'
4     def inner():
5         print(name)   # alex
6     print(inner.__closure__)  # (<cell at 0x0000027D94AFA468: str object at 0x0000027D94B8C148>,)
7     inner()
8     return inner
9 wraaper()
1 # 非闭包
2 name = 'alex'
3 def wraaper():
4     def inner():
5         print(name)       # alex
6     print(inner.__closure__)   # None
7     inner()
8     return inner
9 wraaper()
 1 # 闭包
 2 name = 'alex'
 3 def wraaper(n):
 4     n = 'alex'
 5     def inner():
 6         print(n)   # alex
 7     print(inner.__closure__)  # (<cell at 0x000001F690D1A468: str object at 0x000001F690DAC180>,)
 8     inner()
 9     return inner
10 wraaper(name)
闭包的作用:
当程序执行时,遇到了函数执行,他会在内存中开辟一个空间,即局部命名空间,如果这个函数内部形成了闭包,
那么他就不会随着函数的结束而消失

可迭代对象

什么是可迭代对象?先举一个例子:
1 for i in 'abc':
2     print(i)
3 for i in 123:
4     print(i)   # 报错  TypeError: 'int' object is not iterable
从上面可以看出,整数不是可迭代对象。
如何判断对象为可迭代对象?
1. 对象内部含有__iter__方法就是可迭代对象
2. 可迭代对象满足可迭代协议。
就目前所学知识,可迭代对象主要有:str,list,dict,tuple,set,range()。
判断一个对象是否为可迭代对象,通常有两种方法(__iter__,isinstance):

第一种方法:

1 s1 = 'strs'
2 dic = {'name':'alex'}
3 print('__iter__' in dir(s1))   # True
4 print('__iter__' in dir(dic))  # True

第二种方法:

1 1 # 第二种方法:
2 2 s1 = 'strs'
3 3 dic = {'name':'alex'}
4 4 from collections import Iterable
5 5 from collections import Iterator
6 6 print(isinstance('alex',Iterable))  # True
7 7 print(isinstance('alex',Iterator))  # False
8 8 print(isinstance('alex',str))       # True

迭代器

什么是迭代器?迭代器指对象内部含有__iter__方法且含有__next__方法就是迭代器
1 f = open('register', encoding='utf-8')
2 print('__iter__' in dir(f))
3 print('__next__' in dir(f))
4 print('__iter__' in dir(dict))
5 print('__next__' in dir(dict))
可迭代对象与可迭代器的比较。
1. 可迭代对象不能取值,迭代器是可以取值的
2. 可迭代对象 ————>(转化成)迭代器 (__iter__,iter())
1 lis = [1,2,3] # 可迭代对象
2 itel = lis.__iter__()  # 将列表转化为迭代器  <list_iterator object at 0x0000012DA426C1D0>
3 print(itel)
4 itel = iter(lis)    # # 将列表转化为迭代器  <list_iterator object at 0x000002E0BF96C198>
5 print(itel)
迭代器如何取值? 使用关键字next,每next一次,取一个值。
1 lis = [1,2,3]
2 itel = iter(lis)
3 print(itel.__next__())
4 print(itel.__next__())
5 print(itel.__next__())
6 print(itel.__next__())   # 最后一次报错
从上可以看出,总结迭代器的特点:
1. 可迭代对象不能取值(但可通过切片取值),迭代器是可以取值的,
2. 迭代器非常节省内存,
3. 迭代器每次只会取一个值,
4. 迭代器是单向的,一条路走到头。

for循环的工作原理

1 s1 = 'ndsncla'
2 for i in s1:
3     print(i)
for循环工作机理:
1. 将可迭代对象转化为迭代器
2. 调用__next__方法取值
3. 利用异常处理停止报错
1 s1 = 'ndsncla'
2 s = s1.__iter__()
3 while 1:
4     try:
5         print(s.__next__())
6     except StopIteration:
7         break
原文地址:https://www.cnblogs.com/colin1314/p/9495134.html