Python中迭代器、闭包、装饰器的应用和理解。

Python中迭代器、闭包、装饰器的应用和理解。

实例操作:

[[email protected] 十九天]# ipython3
/usr/python-3.4.6/lib/python3.4/site-packages/IPython/core/history.py:226: UserWarning: IPython History requires SQLite, your history will not be saved
  warn("IPython History requires SQLite, your history will not be saved")
Python 3.4.6 (default, Jan 24 2019, 11:20:45) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from collections import Iterable #导入收藏模块中的Iterable迭代对象函数

In [2]: isinstance([],Iterable)  #判断中括号是否为对待对象
Out[2]: True

In [3]: isinstance((),Iterable) #判断括号是否为对待对象,下面依次类推。
Out[3]: True

In [5]: isinstance("abc",Iterable)
Out[5]: True

In [6]: isinstance({},Iterable)
Out[6]: True

In [7]: g = (x for x in range(5))

In [9]: isinstance(g,Iterable)
Out[9]: True

In [10]: isinstance(100,Iterable) #整型不是迭代对象
Out[10]: False

In [11]: a=[1,2,3]

In [12]: next(a)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-15841f3f11d4> in <module>()
----> 1 next(a)

TypeError: 'list' object is not an iterator  

In [14]: it = iter(a) #将序列增加Iter迭代对象富裕it在判断。

In [15]: next(it)
Out[15]: 1

In [16]: isinstance(it,Iterable)
Out[16]: True

In [17]: next(it)
Out[17]: 2

In [18]: next(it)
Out[18]: 3

In [20]: from collections import Iterator  #引入迭代器模块

In [21]: isinstance(it,Iterable) #It变量既是一个迭代器,又是一个迭代对象。
Out[21]: True

In [22]: isinstance(it,Iterator)
Out[22]: True

In [80]: isinstance(it,Iterable)
Out[80]: True

In [81]: isinstance(it,Iterator)
Out[81]: True

In [82]: isinstance([],Iterator) #换成[]就不是迭代器。
Out[82]: False

In [83]: isinstance((),Iterator)
Out[83]: False

Python中迭代器、闭包、装饰器的应用和理解。

实例操作:

#以下展示全局变量、局部变量的差别。

In [23]: a=10

In [24]: def fun():
    ...:     a=20
    ...:     print(a)
    ...:     

In [25]: fun()#局部变量
20

In [26]: a #全局变量
Out[26]: 10
In [28]: def fun2():
    ...:     global a
    ...:     a=20
    ...:     print(a)
    ...:     

In [29]: a
Out[29]: 10

In [31]: globals()#查看全部的全局变量。
Out[31]: 
{'In': ['',
  'from collections import Iterable',
  'isinstance([],Iterable)',
  'isinstance((),Iterable)',
  'isinstance("abc".Iterable)',
  'isinstance("abc",Iterable)',
  'isinstance({},Iterable)',

Python中迭代器、闭包、装饰器的应用和理解。

实例操作:

In [40]: def fun3():
    ...:     b=10
    ...:     c=20
    ...:     print(c,b)
    ...:     

In [41]: fun3()
20 10

In [42]: fun3
Out[42]: <function __main__.fun3()>

In [43]: b=fun3()
20 10

In [44]: b=fun3

In [45]: b
Out[45]: <function __main__.fun3()>

In [46]: b()
20 10

In [47]: def fun4():
    ...:     def fun5():
    ...:         print("fun5")
    ...:     return fun5 #闭包的外用。
    ...: 
    ...: 

In [48]: fun4()
Out[48]: <function __main__.fun4.<locals>.fun5()> #有个local也是闭包的表现

In [49]: a=fun4

In [52]: a()
Out[52]: <function __main__.fun4.<locals>.fun5()>

In [53]: a=fun4()

In [54]: a()
fun5

#闭包的应用。

In [58]: def outter(num):  #定义两个函数,传参。
    ...:     def iter(num_in):
    ...:         print("this is %d"%num_in)
    ...:         return num+num_in
    ...:     return iter
    ...: 
    ...: 

In [59]: outter(10)(20)  #传参。
this is 20
Out[59]: 30

In [60]: fun=outter(10) #传参赋予fun变量。

In [61]: fun(30)
this is 30
Out[61]: 40
 

#闭包的应用。

In [63]: def line(a,b,x):  #定义X方成的参数。
    ...:     return a+b*x
    ...: 
    ...: 

In [64]: line(1,1,1)   #传送参数
Out[64]: 2

In [65]: line(2,2,2)#传送参数
Out[65]: 6

In [66]: def line_1(x):  #定义参数方程式,传送参数。
    ...:     def line_2(a,b):
    ...:         return a+b*x
    ...:     return line_2

In [69]: l=line_1(2)  #变量赋予第一个参数,传送给函数。

In [70]: l(1,1) #测试第一次。
Out[70]: 3

In [71]: l(2,4)#测试第二次
Out[71]: 10

In [72]: def ret_1(fun): # 定义一个函数。
    ...:     def ret_2():
    ...:         print(fun.__name__)  #打印函数传参的名字。
    ...:         fun()
    ...:     return ret_2
    ...: def fun():
    ...:     print("---1---")
    ...:     

In [73]: doce=ret_1(fun)

In [74]: doce()
fun
---1---

Python中迭代器、闭包、装饰器的应用和理解。

实例操作:

In [72]: def ret_1(fun): #定义一个函数,在另外定义一个函数,传入参数打印。
    ...:     def ret_2():
    ...:         print(fun.__name__)
    ...:         fun()
    ...:     return ret_2
    ...: def fun():
    ...:     print("---1---")
    ...:     

In [73]: doce=ret_1(fun)

In [74]: doce()
fun
---1---

In [76]: @ret_1  #引用装饰器,利用闭包函数可以传送参数进行分解。
    ...: def fun2():
    ...:     print("---func---")
    ...:     

In [77]: doce()
fun
---1---

In [78]: fun2()
fun2
---func---

In [79]: fun2
Out[79]: <function __main__.ret_1.<locals>.ret_2()>#从解释函数中也可以看出,ret_1是主函数,闭包是ret_2。这里会不会有二级闭包呢。

装饰器应用实例:

[[email protected] 十九天]# cat test06.py   #创建一个脚本,这里是写好了,最直接用了。
def deco_1(func):  #函数一
    def wrapped():
        return "b"+func()+"</>"
    return wrapped

def deco_2(func): #函数二
    def wrapped():
        return "I"+func()+"</I>"
    return wrapped

@deco_1  #使用装饰器1,
def fun1():
    return "hello fun1-1"

@deco_2 #使用装饰器2
def fun2():
    return "hello fun2-2"

@deco_1  #同时调用装饰器1,2。
@deco_2
def fun3():
    return "hello world-3"

print(fun1())
print(fun2())
print(fun3())

[[email protected] 十九天]# python3 test06.py 
bhello fun1-1</>
Ihello fun2-2</I>
bIhello world-3</I></> #输出有装饰器1,2传送的参数,这里思考一个问题,没有什么打印两次,只有一次。个人觉得是return函数将函数1的内容,传送给函数2,而不是打印出来。

我尝试将print函数进行两次输出没有成功,有知道网友可以告诉我怎么改。

总结:迭代器好比一个循序递归的函数,函数内部就是逐级往下传递的参数。掌握好如何判别迭代器和迭代对象的判决。

闭包我理解相当于一个子函数,在主函数下面的子函数,先传送主函数的参数,在传送子函数的参数。

装饰器:相当于一个闭包里面将子函数更换,把子函数在外面的定义在传送进闭包中进行输出。