Python中迭代器、閉包、裝飾器的應用和理解。

實例操作:

[root@localhost 十九天]# 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

實例操作:

#以下展示全局變量、局部變量的差別。

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)',

實例操作:

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

實例操作:

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。這裏會不會有二級閉包呢。

裝飾器應用實例:

[root@localhost 十九天]# 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())

[root@localhost 十九天]# python3 test06.py 
bhello fun1-1</>
Ihello fun2-2</I>
bIhello world-3</I></> #輸出有裝飾器1,2傳送的參數,這裏思考一個問題,沒有什麼打印兩次,只有一次。個人覺得是return函數將函數1的內容,傳送給函數2,而不是打印出來。

我嘗試將print函數進行兩次輸出沒有成功,有知道網友可以告訴我怎麼改。

總結:迭代器好比一個循序遞歸的函數,函數內部就是逐級往下傳遞的參數。掌握好如何判別迭代器和迭代對象的判決。

閉包我理解相當於一個子函數,在主函數下面的子函數,先傳送主函數的參數,在傳送子函數的參數。

裝飾器:相當於一個閉包裏面將子函數更換,把子函數在外面的定義在傳送進閉包中進行輸出。

 

 

發佈了35 篇原創文章 · 獲贊 37 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章