一、函數對象: python
函數是第一類對象,即函數能夠看成數據傳遞,它的應用形式也被稱爲高階函數,函數的特性以下:算法
a. 能夠被引用sql
1 # def foo(): 2 # print('from foo') 3 # 4 # func = foo 5 # print(foo) # 不加括號爲foo函數的內存地址 6 # print(func) # func指向foo內存地址 7 # func() # foo內存地址,加()執行 8 ''' 9 結果: 10 <function foo at 0x0000007D79483E18> 11 <function foo at 0x0000007D79483E18> 12 from foo 13 '''
b. 能夠看成參數傳遞數據結構
1 # def foo(): 2 # print('from foo') 3 # 4 # def bar(func): 5 # print(func) 6 # func() 7 # 8 # bar(foo) # foo函數內存地址被看成參數傳遞到bar函數中,並調用 9 10 ''' 11 結果: 12 <function foo at 0x00000049CC9A3E18> 13 from foo 14 '''
c. 返回值能夠是函數閉包
1 # def foo(): 2 # print('from foo') 3 # 4 # def bar(func): 5 # return func 6 # 7 # f = bar(foo) # 去到返回值foo內存地址 8 # print(f) 9 # f() # 調用 10 11 ''' 12 結果: 13 <function foo at 0x000000F005753E18> 14 from foo 15 '''
d. 應用app
1 # def select(sql): 2 # print('----〉select:%s' % sql) 3 # 4 # def insert(sql): 5 # print('----〉insert:%s' % sql) 6 # 7 # def update(sql): 8 # print('----〉update:%s' % sql) 9 # 10 # def delect(sql): 11 # print('----〉delect:%s' % sql) 12 # 13 # sql_dic = { 14 # 'select':select, 15 # 'delect':delect, 16 # 'insert':insert, 17 # 'update':update 18 # } 19 # def main(): 20 # while True: 21 # sql = input('sql>>>').strip() 22 # if not sql:continue 23 # sql_l = sql.split(' ') 24 # if sql_l[0] in sql_dic: 25 # sql_dic[sql_l[0]](sql_l) 26 # 27 # main() 28 ''' 29 結果: 30 sql>>>select * form fafafa 31 ----〉select:['select', '*', 'form', 'fafafa'] 32 sql>>>insert * faormafa faf a 33 ----〉insert:['insert', '*', 'faormafa', '', 'faf', 'a'] 34 sql>>> 35 '''
二、函數的嵌套ide
閉包函數基礎函數
a. 函數的嵌套定義: 函數的嵌套定義:顧名思義就是函數裏面,套函數。應用如閉包、裝飾器工具
1 ''' 2 函數的嵌套定義:顧名思義就是函數裏面,套函數。應用如閉包、裝飾器 3 ''' 4 # 層層調用,層層執行 5 # def f1(): 6 # def f2(): 7 # print('from f2') 8 # def f3(): 9 # print('from f3') 10 # f3() 11 # f2() 12 # f1() 13 ''' 14 結果: 15 from f2 16 from f3 17 '''
b. 函數的嵌套調用:屬於面向過程(分子原子級操做),細分問題測試
1 ''' 2 函數的嵌套調用 3 ''' 4 # 判斷兩個數數字的大小 5 # def max2(x,y): 6 # return x if x > y else y 7 8 # 判斷4個數大小,調用上面的函數 9 # def max4(a,b,c,d): 10 # res1=max2(a,b) 11 # res2=max2(res1,c) 12 # res3=max2(res2,d) 13 # return res3 14 # 15 # print(max4(10,99,31,22)) 16 ''' 17 結果: 18 99 19 '''
三、名稱空間與做用域
a. 名稱空間定義(namespace): 名稱與對象之間的關係,能夠將命名空間看作是字典,其中的鍵是名稱,值是對象
1 ''' 2 一、名稱空間定義(namespace): 名字綁定值時,名字與值得對應關係的存放位置爲名稱空間 3 定義名字的方法 4 ''' 5 # a.導入模塊 6 # import time 7 # b.變量賦值 8 # name='egon' 9 # c.函數定義 10 # def func(): 11 # pass 12 # d.類定義(面向對象) 13 # class Foo: 14 # pass
b. 名稱空間的分類:
1.內置名稱空間:隨着python解釋器的啓動而產生
1 # print(sum) 2 # print(max) 3 # print(min) 4 # 等等,python已啓動,初始定義的功能。 5 ''' 6 結果: 7 <built-in function sum> 8 <built-in function max> 9 <built-in function min> 10 ''' 11 12 # print(max([1,2,3])) 13 14 # builtins dir()函數接受模塊名做爲參數,返回一個排好序的字符串列表,內容是一個模塊裏定義過的名字。 15 # import builtins 16 # dir 對象的內建名稱空間 17 # for i in dir(builtins): 18 # print(i)
2.全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字都會放入改空間
1 # 不在函數和類,定義變量 2 # x=1 3 # if x ==1 : 4 # y=2 5 6 # 不在函數和類,導入模塊 7 # import time 8 9 # 不在函數和類,定義變量 10 # name='egon' 11 12 # 不在類中,定義的函數名 13 # def func(): 14 # pass 15 16 # 不在類中,定義類名 17 # class Foo: 18 # pass 19 20 # x=1 21 # def func(): 22 # money=2000 23 # x=2 24 # print(func) 25 # # 局部x=2 沒有調到 26 # print(x) 27 # # 取到內存地址 28 # print(func) 29 # # 執行函數能夠調到全局變量 30 # func() 31 # # print(money) # money屬於局部變量,調用不了
3.局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束解綁定
1 # x=10000 2 # def func(): 3 # x = 1 局部變量 4 # x=1 5 # def f1(): 6 # pass
c. 做用域:爲名稱空間的具體應用。他們之間的關係,以下對應:
1.全局做用域:內置名稱空間,全局名層空間
2.局部做用:局部名稱空間
d. 做用於的優先級順序:局部名稱空間---》全局名層空間---》內置名稱空間
1 ''' 2 # 後生效 3 # x=1 4 # def func(): 5 # # 優先生效 6 # x = 2 7 # print(x) 8 # sum = 123123 9 # print(sum) 10 # func() 11 ''' 12 結果: 13 2 14 123123 15 ''' 16 17 # x = 1 18 # def func(): 19 # x=2 20 # 21 # func() 22 # 23 # print(x) 24 ''' 25 結果: 26 1 27 '''
1.查看全局做用域內的名字:gloabls()
2.查看局局做用域內的名字:locals()
1 ''' 2 查看全局做用域內的名字:gloabls() 3 查看局部做用域內的名字:locals() 4 ''' 5 x=1000 6 def func(): 7 x=2 8 # 全局做用域內 9 print(globals()) 10 # 局部做用域 11 print(locals()) 12 func() 13 # 全局做用域內 14 print(globals()) 15 # 局部做用域 16 print(locals()) 17 # 在全局環境中,locals()和globals()是同樣的,可是在局部環境中,就不同了 18 print(globals() is locals()) 19 ''' 20 結果: 21 {'__name__': '__main__', '__doc__': '\n名稱空間與做用域\n一、名稱空間定義(namespace): 名稱與對象之間的關係,能夠將命名空間看作是字典,其中的鍵是名稱,值是對象\n二、名稱空間的分類: \n 內置名稱空間:隨着python解釋器的啓動而產生\n 全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字都會放入改空間\n 局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束解綁定\n三、做用域:爲名稱空間的具體應用。他們之間的關係,以下對應:\n 全局做用域:內置名稱空間,全局名層空間\n 局部做用:局部名稱空間\n四、做用於的優先級順序:局部名稱空間---》全局名層空間---》內置名稱空間\n 查看全局做用域內的名字:gloabls()\n 查看局局做用域內的名字:locals()\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000D9A5DCB160>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/old_boy/old_boy_17_04/名稱空間與做用域.py', '__cached__': None, 'x': 1000, 'func': <function func at 0x000000D9A5B03E18>} 22 {'x': 2} 23 {'__name__': '__main__', '__doc__': '\n名稱空間與做用域\n一、名稱空間定義(namespace): 名稱與對象之間的關係,能夠將命名空間看作是字典,其中的鍵是名稱,值是對象\n二、名稱空間的分類: \n 內置名稱空間:隨着python解釋器的啓動而產生\n 全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字都會放入改空間\n 局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束解綁定\n三、做用域:爲名稱空間的具體應用。他們之間的關係,以下對應:\n 全局做用域:內置名稱空間,全局名層空間\n 局部做用:局部名稱空間\n四、做用於的優先級順序:局部名稱空間---》全局名層空間---》內置名稱空間\n 查看全局做用域內的名字:gloabls()\n 查看局局做用域內的名字:locals()\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000D9A5DCB160>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/old_boy/old_boy_17_04/名稱空間與做用域.py', '__cached__': None, 'x': 1000, 'func': <function func at 0x000000D9A5B03E18>} 24 {'__name__': '__main__', '__doc__': '\n名稱空間與做用域\n一、名稱空間定義(namespace): 名稱與對象之間的關係,能夠將命名空間看作是字典,其中的鍵是名稱,值是對象\n二、名稱空間的分類: \n 內置名稱空間:隨着python解釋器的啓動而產生\n 全局名稱空間:文件的執行會產生全局名稱空間,指的是文件級別定義的名字都會放入改空間\n 局部名稱空間:調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束解綁定\n三、做用域:爲名稱空間的具體應用。他們之間的關係,以下對應:\n 全局做用域:內置名稱空間,全局名層空間\n 局部做用:局部名稱空間\n四、做用於的優先級順序:局部名稱空間---》全局名層空間---》內置名稱空間\n 查看全局做用域內的名字:gloabls()\n 查看局局做用域內的名字:locals()\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000000D9A5DCB160>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/old_boy/old_boy_17_04/名稱空間與做用域.py', '__cached__': None, 'x': 1000, 'func': <function func at 0x000000D9A5B03E18>} 25 True 26 '''
四、閉包函數
函數嵌套的一種方式,必須遵照如下規則:
a. 定義在內部函數
b. 包含對外部做用域而非全局做用域的引用,該內部函數就成爲閉包函數
1 # 定義實例,對象隱藏,全局不可見 2 # def f1(): 3 # # x內部隱藏,全局不可見 4 # x = 1 5 # def f2(): 6 # print(x) 7 # 8 # return f2 9 # 10 # f=f1() 11 # # print(f) 12 # # x由於隱藏,因此全局做用域無效 13 # x=100000000000000000000000000 14 # f() 15 ''' 16 結果: 17 1 18 '''
閉包應用:惰性計算
1 # 爬網頁,老式方法 2 # res=urlopen('http://crm.oldboyedu.com').read() 3 # print(res.decode('utf-8')) 4 # from urllib.request import urlopen 5 6 # def index(url): 7 # def get(): 8 # return urlopen(url).read() 9 # return get 10 11 # 存在內存裏 12 # oldboy=index('http://crm.oldboyedu.com') 13 # 何時想用,何時用 14 # print(oldboy().decode('utf-8')) 15 16 # 閉包函數相對與普通函數會多出一個__closure__的屬性,裏面定義了一個元組用於存放全部的cell對象, 17 # 每一個cell對象一一保存了這個閉包中全部的外部變量 18 # print(oldboy.__closure__[0].cell_contents) 19 20 21 22 23 24 # def f1(): 25 # x = 1 26 # y = 2 27 # def f2(): 28 # print(x,y) 29 # return f2 30 # 31 # a = f1() 32 # # a() 33 # print(a.__closure__[1].cell_contents) 34 ''' 35 結果: 36 2 37 '''
裝飾器:修飾別人的工具,修飾添加功能,工具指的是函數
裝飾器自己能夠是任何可調用對象,被裝飾的對象也能夠是任意可調用對象
爲何要用裝飾器?
a. 開放封閉原則:對修改是封閉的,對擴展是開放的
b. 裝飾器就是爲了在不修改被裝飾對象的源代碼以及調用方式的前提下,爲期添加新功能
一、裝飾器的基本寫法
1 ''' 2 一、裝飾器的基本寫法 3 ''' 4 # import time 5 # 6 # def timmer(func): 7 # def wrapper(): 8 # # 在運行函數前執行,time.time()爲當前時間(格林威治時間1970到如今的秒數) 9 # start_time = time.time() 10 # # 被裝飾函數執行,沒有返回值,默認爲 11 # res = func() 12 # # 在函數運行後執行 13 # stop_time = time.time() 14 # print('run time is %s' %(stop_time-start_time)) 15 # return wrapper 16 # 17 # @timmer # index = timmer(index) 18 # def index(): 19 # time.sleep(3) 20 # print('welcome to index') 21 # 22 # index() # wrapper(index) ---> index() 23 ''' 24 結果: 25 welcome to index 26 run time is 3.000379800796509 27 '''
二、多實例添加,及傳參數函數
1 ''' 2 二、多實例添加,及傳參數函數 3 ''' 4 # import time 5 # def timmer(func): 6 # # 傳遞參數,保證通用性,應爲可變長參數(*args,**kwargs),可接受全部類型的實參 7 # def wrapper(*args,**kwargs): 8 # start_time=time.time() 9 # # 傳遞參數,保證通用性,應爲可變長參數(*args,**kwargs),可接受全部類型的實參 10 # # 有返回值,存值 11 # res=func(*args,**kwargs) 12 # stop_time=time.time() 13 # print('run time is %s' %(stop_time-start_time)) 14 # # 有返回值,返回 15 # return res 16 # return wrapper 17 # 18 # @timmer #index=timmer(index) 19 # def index(): 20 # time.sleep(3) 21 # print('welcome to index') 22 # # 有返回值,定義 23 # return 1 24 # 25 # #再次調用指須要加@timmer 26 # @timmer 27 # def foo(name): 28 # time.sleep(1) 29 # print('from foo') 30 # 31 # # 有返回值,傳值打印 32 # res=index() #wrapper() 33 # print(res) 34 # 35 # res1=foo('shuyang') #res1=wrapper('egon') 36 # print(res1) 37 ''' 38 運行結果: 39 welcome to index 40 run time is 3.000380039215088 41 1 42 from foo 43 run time is 1.0001308917999268 44 None 45 '''
三、登陸權限,一次登陸,屢次使用
1 ''' 2 三、登陸權限,一次登陸,屢次使用 3 ''' 4 # 全局,記錄用戶狀態 5 # login_user={'user':None,'status':False} 6 # def auth(func): 7 # def wrapper(*args,**kwargs): 8 # # 判斷用戶狀態,有直接返回結果 9 # if login_user['user'] and login_user['status']: 10 # res=func(*args,**kwargs) 11 # return res 12 # # 不然,繼續 13 # else: 14 # name=input('name: ') 15 # password=input('passwd: ') 16 # if name == 'shuyang' and password == '123': 17 # login_user['user']='shuyang' 18 # login_user['status']=True 19 # print('\033[45mlogin successful\033[0m') 20 # res=func(*args,**kwargs) 21 # return res 22 # else: 23 # print('\033[45mlogin err\033[0m') 24 # return wrapper 25 # 26 # @auth 27 # def index(): 28 # print('welcome to index page') 29 # @auth 30 # def home(name): 31 # print('%s welcome to home page' %name) 32 # index() 33 # home('shuyang') 34 35 ''' 36 結果: 37 name: shuyang 38 passwd: 123 39 login successful 40 welcome to index page 41 shuyang welcome to home page 42 '''
四、多裝飾器,執行順序
1 ''' 2 四、多裝飾器,執行順序 3 ''' 4 # import time 5 # def timmer(func): 6 # def wrapper(*args,**kwargs): 7 # print('timmer--->wrapper') 8 # start_time=time.time() 9 # res=func(*args,**kwargs) 10 # stop_time=time.time() 11 # print('run time is %s' %(stop_time-start_time)) 12 # return res 13 # return wrapper 14 # 15 # login_user={'user':None,'status':False} 16 # def auth(func): 17 # def wrapper(*args,**kwargs): 18 # print('auth--->wrapper') 19 # if login_user['user'] and login_user['status']: 20 # res=func(*args,**kwargs) 21 # return res 22 # else: 23 # name=input('name: ') 24 # password=input('pwd: ') 25 # if name == 'shuyang' and password == '123': 26 # login_user['user']='shuyang' 27 # login_user['status']=True 28 # print('\033[45mlogin successful\033[0m') 29 # res=func(*args,**kwargs) 30 # return res 31 # else: 32 # print('\033[45mlogin err\033[0m') 33 # return wrapper 34 # 35 # # 順序執行 36 # @auth # timmer = auth--->wrapper--->timmer 37 # @timmer # index = auth--->wrapper--->timmer--->wrapper(index) 38 # def index(): 39 # time.sleep(3) 40 # print('welcome to index page') 41 # 42 # # 順序執行,調轉則timmer包含auth增長了程序執行時間 43 # @timmer # auth = timmer--->wrapper--->auth 44 # @auth # home = timmer--->wrapper--->auth---->wrapper(home) 45 # def home(name): 46 # time.sleep(3) 47 # print('%s welcome to home page' %name) 48 # index() 49 # home('shuyang') 50 ''' 51 結果: 52 auth--->wrapper 53 name: shuyang 54 pwd: 123 55 login successful 56 timmer--->wrapper 57 welcome to index page 58 run time is 3.000378131866455 59 timmer--->wrapper 60 auth--->wrapper 61 shuyang welcome to home page 62 run time is 3.000382423400879 63 '''
五、有參裝飾器
1 ''' 2 五、有參裝飾器 3 ''' 4 # login_user={'user':None,'status':False} 5 # 在包一個函數,根據做用域特性傳值 6 # def auth(db_tpye): 7 # def auth2(func): 8 # def wrapper(*args,**kwargs): 9 # #傳進來了 10 # if db_tpye == 'file': 11 # if login_user['user'] and login_user['status']: 12 # res=func(*args,**kwargs) 13 # return res 14 # else: 15 # name=input('name: ') 16 # password=input('pwd: ') 17 # if name == 'shuyang' and password == '123': 18 # login_user['user']='egon' 19 # login_user['status']=True 20 # print('\033[45mlogin successful\033[0m') 21 # res=func(*args,**kwargs) 22 # return res 23 # else: 24 # print('\033[45mlogin err\033[0m') 25 # elif db_tpye == 'ldap': 26 # print('db_type---->ldap') 27 # return wrapper 28 # return auth2 29 # 30 # @auth('file') 31 # def index(): 32 # print('welcome to index page') 33 # 34 # @auth('ldap') 35 # def home(name): 36 # print('%s welcome to home page' %name) 37 # index() 38 # home('shuyang') 39 ''' 40 結果: 41 name: shuyang 42 pwd: 123 43 login successful 44 welcome to index page 45 db_type---->ldap 46 '''
六、裝飾器@functools.wraps
a.官網裝飾器定義:
裝飾器是一個函數,其主要用途是包裝另外一個函數或類。這種包裝的首要目的是透明地修改或加強被包
裝對象的行爲。
b.@functools.wraps做用:
由於裝飾器是一個閉包函數,怎樣能獲取被修飾函數的詳細信息,如:__name__。
此類實際調用函數的屬性。@functools.wraps就提供了該功能。
它是如何實現的,下面的例子是經過反射的原理把func的一些屬性更新給了callf函數。原func的屬性
不變。可是callf的屬性仍是跟原func不徹底同樣,so,若有相似的問題,還須要本身寫。
具體,請看將來的類章節。
1 import functools 2 import sys 3 debug_log = sys.stderr 4 5 def trace(func): 6 if debug_log: 7 @functools.wraps(func) 8 def callf(*args, **kwargs): 9 """A wrapper function.""" 10 debug_log.write('Calling function: {}\n'.format(func.__name__)) 11 res = func(*args, **kwargs) 12 debug_log.write('Return value: {}\n'.format(res)) 13 return res 14 return callf 15 else: 16 return func 17 18 @trace 19 def square(x): 20 """Calculate the square of the given number.""" 21 return x * x 22 23 if __name__ == '__main__': 24 print(square(3)) 25 print(square.__doc__) 26 print(square.__name__) 27 ''' 28 結果: 29 Calling function: square 30 Return value: 9 31 9 32 Calculate the square of the given number. 33 square 34 35 不加結果@functools.wraps(func): 36 Calling function: square 37 Return value: 9 38 9 39 A wrapper function. 40 callf 41 '''
一、迭代的概念:
重複+上一次迭代的結果爲下一次迭代的初始值,重複的過程稱爲迭代,每次重複即一次迭代,而且每次迭代的結果是下一次迭代的初始值
a. 不是迭代器
1 # while True: #只知足重複,於是不是迭代 2 # print('====>') 3 4 ''' 5 結果: 6 ====> 7 ====> 8 ====> 9 '''
b. 迭代while寫法
1 # 下面才爲迭代 2 # list列表是可迭代對象 3 # l = [1, 2, 3] 4 # count = 0 5 # while count < len(l): # 只知足重複,於是不是迭代 6 # print('====>', l[count]) 7 # count += 1 8 ''' 9 結果: 10 ====> 1 11 ====> 2 12 ====> 3 13 ''' 14 15 # tuple元祖是可迭代對象 16 # l = (1, 2, 3) 17 # count = 0 18 # while count < len(l): # 只知足重複,於是不是迭代 19 # print('====>', l[count]) 20 # count += 1 21 ''' 22 結果: 23 ====> 1 24 ====> 2 25 ====> 3 26 ''' 27 28 # 字符串是可迭代對象 29 # s='hello' 30 # count = 0 31 # while count < len(s): 32 # print('====>', s[count]) 33 # count += 1 34 ''' 35 結果: 36 ====> h 37 ====> e 38 ====> l 39 ====> l 40 ====> o 41 '''
ps.總結:while這種方式,指能迭代有序的對象,那無需的想字典、集合、文件如何操做??
二、爲何要有迭代器?
對於沒有索引的數據類型,必須提供一種不依賴索引的迭代方式
1 #有序的 2 # [1,2].__iter__() 3 # 'hello'.__iter__() 4 # (1,2).__iter__() 5 #無序的 6 # {'a':1,'b':2}.__iter__() 7 # {1,2,3}.__iter__()
a. 可迭代的對象:內置__iter__方法的,都是可迭代的對象
b. 迭代器:執行__iter__方法,獲得的結果就是迭代器,迭代器對象有__next__方法
1 # 列表,可迭代的對象轉迭代器使用 2 # i=[1,2,3].__iter__() 3 # 4 # print(i) # 打印一個內存地址 5 ''' 6 結果: 7 <list_iterator object at 0x000000F7C74991D0> 8 ''' 9 # 10 # print(i.__next__()) 11 # print(i.__next__()) 12 # print(i.__next__()) 13 # print(i.__next__()) #拋出異常:StopIteration 14 ''' 15 結果: 16 1 17 Traceback (most recent call last): 18 2 19 File "D:/old_boy/old_boy_17_04/迭代器.py", line 125, in <module> 20 3 21 print(i.__next__()) #拋出異常:StopIteration 22 StopIteration 23 ''' 24 25 # 字典,可迭代的對象轉迭代器使用 26 # i={'a':1,'b':2,'c':3}.__iter__() 27 # 28 # print(i.__next__()) 29 # print(i.__next__()) 30 # print(i.__next__()) 31 # print(i.__next__()) #拋出異常:StopIteration 32 ''' 33 結果: 34 Traceback (most recent call last): 35 File "D:/old_boy/old_boy_17_04/迭代器.py", line 142, in <module> 36 print(i.__next__()) 37 StopIteration 38 a 39 b 40 c 41 ''' 42 43 # 字典,可迭代的對象轉迭代器使用之異常處理 44 # dic={'a':1,'b':2,'c':3} 45 # i=dic.__iter__() 46 # while True: 47 # try: 48 # key=i.__next__() 49 # print(dic[key]) 50 # except StopIteration: 51 # break 52 ''' 53 結果: 54 1 55 2 56 3 57 ''' 58 59 # 集合,可迭代的對象轉迭代器使用 60 # __iter__ == iter() 61 # s={'a',3,2,4} 62 # s.__iter__() #iter(s) 63 # i=iter(s) 64 # print(next(i)) 65 # print(next(i)) 66 # print(next(i)) 67 # print(next(i)) 68 # print(next(i)) 69 ''' 70 結果: 71 Traceback (most recent call last): 72 2 73 File "D:/old_boy/old_boy_17_04/迭代器.py", line 180, in <module> 74 print(next(i)) 75 3 76 StopIteration 77 4 78 a 79 ''' 80 81 # ps.字符串,內置函數 82 # s='hello' 83 # print(s.__len__()) 84 # 85 # print(len(s)) 86 # 總結: 87 # len(s)====== s.__len__()
三、如何判斷一個對象是可迭代的對象,仍是迭代器對象?
a. 討論數據對象
1 # 'abc'.__iter__() # 字符串str 2 # ().__iter__() # 元祖tuple 3 # [].__iter__() # 列表list 4 # {'a':1}.__iter__() # 字典dict 5 # {1,2}.__iter__() # 集合set 6 # f = open('a.txt','w') # 文件file 7 # f.__iter__()
b. 可迭代對象:只有__iter__方法,執行該方法獲得的迭代器對象。及可迭代對象經過__iter__轉成迭代器對象
1 ''' 2 b. 可迭代對象:只有__iter__方法,執行該方法獲得的迭代器對象。及可迭代對象經過__iter__轉成迭代器對象 3 ''' 4 # 下列數據類型都是可迭代的對象 5 # from collections import Iterable,Iterator 6 # print(isinstance('abc',Iterable)) 7 # print(isinstance([],Iterable)) 8 # print(isinstance((),Iterable)) 9 # print(isinstance({'a':1},Iterable)) 10 # print(isinstance({1,2},Iterable)) 11 # f = open('a.txt','w') 12 # print(isinstance(f,Iterable)) 13 ''' 14 結果: 15 True 16 True 17 True 18 True 19 True 20 True 21 '''
c. 迭代器對象:對象有__next__,對象有__iter__,對於迭代器對象來講,執行__iter__方法,獲得的結果仍然是它自己
1 ''' 2 c. 迭代器對象:對象有__next__,對象有__iter__,對於迭代器對象來講,執行__iter__方法,獲得的結果仍然是它自己 3 ''' 4 # 只有文件是迭代器對象 5 # from collections import Iterable,Iterator 6 # print(isinstance('abc',Iterator)) 7 # print(isinstance([],Iterator)) 8 # print(isinstance((),Iterator)) 9 # print(isinstance({'a':1},Iterator)) 10 # print(isinstance({1,2},Iterator)) 11 # f = open('a.txt','w') 12 # print(isinstance(f,Iterator)) 13 ''' 14 結果: 15 False 16 False 17 False 18 False 19 False 20 True 21 '''
四、可迭代對象經過__iter__轉成迭代器對象
a.迭代協議:
對象有__next__
對象有__iter__,對於迭代器對象來講,執行__iter__方法,獲得的結果仍然是它自己
1 # 對象有__iter__,對於迭代器對象來講,執行__iter__方法,獲得的結果仍然是它自己 2 # f = open('a.txt','r') 3 # f1=f.__iter__() 4 # 5 # print(f) 6 # print(f1) 7 # print(f is f1) 8 ''' 9 結果: 10 <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'> 11 <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'> 12 True 13 ''' 14 15 # 可迭代對象list,能夠看出就是一個迭代器 16 # l=[] 17 # i=l.__iter__() 18 # 19 # print(i.__iter__()) 20 # print(i) 21 # print(l) 22 ''' 23 結果: 24 <list_iterator object at 0x00000038DA2B9320> 25 <list_iterator object at 0x00000038DA2B9320> 26 [] 27 ''' 28 29 # dict字典,之前的調用方式 30 # dic={'name':'egon','age':18,'height':'180'} 31 # print(dic.items()) 32 # 33 # for k,v in dic.items(): 34 # print(k,v) 35 ''' 36 結果: 37 dict_items([('name', 'egon'), ('age', 18), ('height', '180')]) 38 name egon 39 age 18 40 height 180 41 ''' 42 43 # dict字典,while迭代器調用 44 # dic={'name':'egon','age':18,'height':'180'} 45 # i=iter(dic) 46 # while True: 47 # try: 48 # k=next(i) 49 # print(k) 50 # except StopIteration: 51 # break 52 ''' 53 結果: 54 name egon 55 age 18 56 height 180 57 ''' 58 59 # for迭代調用 60 # dic={'name':'egon','age':18,'height':'180'} 61 # for k in dic: #i=iter(dic) k=next(i) 62 # print(k) 63 # print(dic[k]) 64 ''' 65 結果: 66 name 67 egon 68 age 69 18 70 height 71 180 72 ''' 73 74 # list的for循環迭代 75 # l=['a','b',3,9,10] 76 # for i in l: 77 # print(i) 78 ''' 79 結果: 80 a 81 b 82 3 83 9 84 10 85 ''' 86 87 # 文件迭代器,直接能夠for循環迭代 88 # with open('a.txt','r',encoding='utf-8') as f: 89 # for line in f: 90 # print(line.strip()) 91 ''' 92 結果: 93 1111 94 2222 95 3333 96 4444 97 5555 98 6666 99 7777 100 '''
ps.
總結:
python中for就是經過迭代的方式來實現調用的。while只是普通的循環
for迭代 == while + try...except...(異常處理方式)
五、 迭代器的優勢和缺點
a.優勢:
1. 提供了一種不依賴下標的迭代方式
1 # 提供了一種不依賴下標的迭代方式 2 # l=[10000,2,3,4,5] 3 # i=iter(l) 4 # print(i) 5 # print(next(i)) 6 ''' 7 結果: 8 <list_iterator object at 0x000000696CAF91D0> 9 10000 10 '''
2. 就迭代器自己來講,更節省內存。迭代一個值,原來迭代的值丟棄
b.缺點:
1. 沒法獲取迭代器對象的長度
2. 不如序列類型取值靈活,是一次性的,只能日後取值,不能往前退
1 # 不如序列類型取值靈活,是一次性的,只能日後取值,不能往前退 2 # f=open('a.txt',encoding='utf-8') 3 # 4 # for line in f.readlines(): 5 # print(line.strip()) 6 # 7 # print(next(f)) 8 ''' 9 Traceback (most recent call last): 10 1111 11 File "D:/old_boy/old_boy_17_04/迭代器.py", line 398, in <module> 12 2222 13 3333 14 4444 15 5555 16 6666 17 7777 18 print(next(f)) 19 StopIteration 20 ''' 21 22 # f=open('a.txt',encoding='utf-8') 23 # print(next(f)) 24 # for line in f: 25 # print(line.strip()) 26 ''' 27 結果: 28 1111 29 30 2222 31 3333 32 4444 33 5555 34 6666 35 7777 36 ''' 37 38 39 # 列表迭代 40 # l=[10000,2,3,4,5] 41 # 42 # i=iter(l) 43 # 44 # for item in i: 45 # print(item) 46 # print('=============================') 47 # for item in i: 48 # print(item) 49 ''' 50 結果: 51 10000 52 2 53 3 54 4 55 5 56 ============================= 57 '''
ps. 枚舉函數enumerate(),實際也是迭代器
l=[10000,2,3,4,5]
i=enumerate(l)
print(next(i))
print(next(i))
生成器: 只要函數體包含yield關鍵字,該函數就是生成器函數。
return函數
1 ''' 2 return 3 ''' 4 # def foo(): 5 # return 1 6 # return 2 7 # return 3 8 # return 4 9 # 10 # res1=foo() 11 # print(res1) 12 # 13 # res2=foo() 14 # print(res2) 15 ''' 16 結果: 17 1 18 1 19 '''
一、生成器就是迭代器
1 ''' 2 一、生成器就是迭代器 3 ''' 4 # def foo(): 5 # print('first') 6 # yield 1 7 # print('second') 8 # yield 2 9 # print('third') 10 # yield 3 11 # print('fourth') 12 # yield 4 13 # print('fifth') 14 # 15 # g=foo() 16 # for i in g: 17 # print(i) 18 ''' 19 結果: 20 first 21 1 22 second 23 2 24 third 25 3 26 fourth 27 4 28 fifth 29 ''' 30 # print(g) 31 # 32 # print(next(g)) #觸發迭代器g的執行,進而觸發函數的執行 33 # print(next(g)) 34 # print(next(g)) 35 # print(next(g)) 36 # print(next(g)) 37 ''' 38 結果2 39 <generator object foo at 0x00000023D6DBB200> 40 first 41 1 42 second 43 2 44 third 45 3 46 fourth 47 4 48 fifth 49 Traceback (most recent call last): 50 File "D:/old_boy/old_boy_17_04/生成器.py", line 54, in <module> 51 print(next(g)) 52 StopIteration 53 '''
二、生成器簡單調用
1 ''' 2 二、生成器簡單調用 3 ''' 4 # def counter(n): 5 # print('start...') 6 # i=0 7 # while i < n: 8 # yield i 9 # i+=1 10 # print('end...') 11 # 12 # 13 # g=counter(5) 14 # print(g) 15 # print(next(g)) 16 # print(next(g)) 17 # print(next(g)) 18 # print(next(g)) 19 # print(next(g)) 20 # print(next(g)) 21 ''' 22 結果: 23 Traceback (most recent call last): 24 <generator object counter at 0x000000089E27B200> 25 File "D:/old_boy/old_boy_17_04/生成器.py", line 109, in <module> 26 start... 27 print(next(g)) 28 0 29 StopIteration 30 1 31 2 32 3 33 4 34 end... 35 '''
三、總結:yield的功能
a. 至關於爲函數封裝好__iter__和__next__
b. return只能返回一次值,函數就終止了,而yield能返回屢次值,每次返回都會將函數暫停,下一次next會從上一次暫停的位置繼續執行
四、yield程序實例(tail -f a.txt | grep 'python' 類功能python程序版)
1 #tail -f a.txt | grep 'python' 類功能python程序版 2 3 # import time 4 # def tail(filepath): 5 # ''' 6 # tail功能 7 # :param filepath: 文件路徑 8 # :return: 至關於return文件最後一行,後等待文件輸入 9 # ''' 10 # with open(filepath,encoding='utf-8') as f: 11 # ''' 12 # seek(offset,whence=0) 13 # offset:開始的偏移量,也就是表明須要移動偏移的字節數 14 # whence:給offset參數一個定義,表示要從哪一個位置開始偏移;0表明從文件開頭開始算起, 15 # 1表明從當前位置開始算起,2表明從文件末尾算起。默認爲0 16 # ''' 17 # f.seek(0,2) 18 # while True: 19 # line=f.readline().strip() 20 # if line: 21 # yield line 22 # else: 23 # time.sleep(0.2) 24 # 25 # #至關於return文件最後一行,後繼續等待next下次調用 26 # t=tail('a.txt') 27 # 28 # # 測試tail功能是否有效 29 # # for line in t: 30 # # print(line) 31 # 32 # def grep(pattern,lines): 33 # ''' 34 # grep 功能實現 35 # :param pattern: 校驗關鍵字 36 # :param lines: 要校驗的行 37 # :return: 至關於return符合檢驗的行,後等待行繼續調用輸入 38 # ''' 39 # for line in lines: 40 # if pattern in line: 41 # yield line 42 # 43 # 44 # g=grep('python',tail('a.txt')) 45 # #返回內存地址 46 # print(g) 47 # 48 # #迭代輸出 49 # for i in g: 50 # print(i)
一、數學運算
abs(), round(),pow(),divmod(),max(),min(),sum()
1 ''' 2 一、數學運算 3 ''' 4 # abs(-5) # 取絕對值,也就是5 5 # round(2.623423, 4) # 四捨五入取整,也就是3.0, 4爲精準到四位四捨五入 6 # pow(2, 3) # 至關於2**3,若是是pow(2, 3, 5),至關於2**3 % 5 7 # divmod(9, 2) # 返回除法結果和餘數 8 # max([1, 5, 2, 9]) # 求最大值 9 # min([9, 2, -4, 2]) # 求最小值 10 # sum([2, -1, 9, 12]) # 求和
二、工廠函數
int(), float(), str(), bool(), slice(), list(), tuple(), dict(), set(), frozenset()
1 # int("5") # 轉換爲整數 integer 2 # float(2) # 轉換爲浮點數 float 3 # str(2.3) # 轉換爲字符串 string 4 # bool(0) # 轉換爲相應的真假值,在Python中,0至關於False在Python中,下列對象都至關於False:[], (), {}, 0, None, 0.0, '' 5 # slice(5, 2, -1) # 構建下標對象 slice,切片函數 6 # list((1, 2, 3)) # 轉換爲表 list 7 # tuple([2, 3, 4]) # 轉換爲定值表 tuple 8 # dict(a=1, b="hello", c=[1, 2, 3]) # 構建詞典 dictionary 9 # set() 建立集合函數 10 # frozenset() 建立一個不可修改的集合 如:s=frozenset({1,2}) # 定義不可變集合
三、類型轉換
ord(), chr(), bin(), hex(), oct(), complex()
1 # ord("A") # "A"字符對應的數值 2 # chr(65) # 數值65對應的字符 3 # bin(56) # 返回一個字符串,表示56的二進制數 4 # hex(56) # 返回一個字符串,表示56的十六進制數 5 # oct(56) # 返回一個字符串,表示56的八進制數 6 # complex(3, 9) # 返回複數 3 + 9j
四、序列操做
all(), any(), sorted(), reversed()
1 # all([True, 1, "hello!"]) # 是否全部的元素都至關於True值 2 # any(["", 0, False, [], None]) # 是否有任意一個元素至關於True值 3 # sorted([1,5,3]) # 返回正序的序列,也就是[1,3,5] 4 # reversed([1,5,3]) # 返回反序的序列,也就是[3,5,1]
五、編譯執行函數
repr(), compile(), eval(), exec()
1 # repr(me) # 返回一個對象的字符串表示。有時可使用這個函數來訪問操做。 2 # compile("print('Hello')",'test.py','exec') # 編譯字符串成爲code對象 3 # eval("1 + 1") # 解釋字符串表達式。參數也能夠是compile()返回的code對象 4 ''' 5 # cmd='print("你瞅啥")' 6 # 7 # dic="{'a':1,'b':2}" 8 # d=eval(dic) 9 # print(type(d),d['a']) 10 # 11 # with open('user.db','w',encoding='utf-8') as f: 12 # user_dic={'name':'egon','password':'123'} 13 # f.write(str(user_dic)) 14 # 15 # with open('user.db','r',encoding='utf-8') as f: 16 # dic=f.read() 17 # print(dic,type(dic)) 18 # dic=eval(dic) 19 # print(dic['name']) 20 ''' 21 # exec("print('Hello')") # exec()執行字符串或complie方法編譯過的字符串,沒有返回值
六、幫助函數
dir(), help(), id(), len(), challables()
1 ''' 2 六、幫助函數 3 ''' 4 # dir() 不帶參數時返回當前範圍內的變量,方法和定義的類型列表,帶參數時返回參數的屬性,方法列表 5 ''' 6 l=[] 7 print(dir(l)) #查看一個對象下面的屬性 8 ''' 9 # help() 返回對象的幫助文檔 10 ''' 11 print(help(l)) 12 ''' 13 # id() 返回對象的內存地址 14 ''' 15 # x=1 16 # y=x 17 # print(id(x),id(y)) 18 # 19 # print(x is y) #判斷的是身份 20 ''' 21 # len() 返回對象長度,參數能夠是序列類型(字符串,元組或列表)或映射類型(如字典) 22 # challable() 判斷對象是否能夠被調用,能被調用的對象就是一個callables對象,好比函數和帶有__call__()的實例 23 ''' 24 def func(): 25 pass 26 print(callable(func)) 27 '''
七、做用域查看函數
globals(), locals(), vars()
1 # globals() 返回一個描述當前全局變量的字典 2 # locals() 打印當前可用的局部變量的字典 3 # vars() # 1. 當函數不接收參數時,其功能和locals函數同樣,返回當前做用域內的局部變量。 4 # 2. 當函數接收一個參數時,參數能夠是模塊、類、類實例,或者定義了__dict__屬性的對象。
八、迭代器函數
iter(), next(), enumerate(), range()#python3中爲生成一個迭代器
1 ''' 2 八、迭代器函數 3 ''' 4 ''' 5 iter(o[, sentinel]) 6 返回一個iterator對象。該函數對於第一個參數的解析依賴於第二個參數。 7 若是沒有提供第二個參數,參數o必須是一個集合對象,支持遍歷功能(__iter__()方法)或支持序列功能(__getitem__()方法), 8 參數爲整數,從零開始。若是不支持這兩種功能,將處罰TypeError異常。 9 若是提供了第二個參數,參數o必須是一個可調用對象。在這種狀況下建立一個iterator對象,每次調用iterator的next()方法來無 10 參數的調用o,若是返回值等於參數sentinel,觸發StopIteration異常,不然將返回該值。 11 ''' 12 # next() 返回一個可迭代數據結構(如列表)中的下一項 13 # enumerate() # 返回一個能夠枚舉的對象,該對象的next()方法將返回一個元組 14 # x=range(10) 15 # enumerate([1,2,3]).__next__() 16 # range() 根據須要生成一個指定範圍的數字,能夠提供你須要的控制來迭代指定的次數
九、其餘函數
hash(), filter(), format(), input(), open(), print(), zip(), map(), __import__
1 # hash() 哈希值用於快遞比價字典的鍵。 2 # 1. 只要校驗的內容一致,那hash獲得結果永遠同樣 3 # 2. 不可逆 4 # 3. 只要採用的哈希算法同樣,那不管被校驗的內容有多長,hash的到的結果長度都同樣 5 # print(hash('asdfasdfsadf')) 6 # print(hash('asdfasdfsadf')) 7 8 # filter() 過濾器,構造一個序列,等價於[ item for item in iterables if function(item)],在函數中設定過濾條件,逐一循環迭代器中的元素,將返回值爲True時的元素留下,造成一個filter類型數據 9 ''' 10 filter(function, iterable) 11 參數function:返回值爲True或False的函數,能夠爲None。 12 參數iterable:序列或可迭代對象。 13 >>> def bigerthan5(x): 14 ... return x > 5 15 >>> filter(bigerthan5, [3, 4, 5, 6, 7, 8]) 16 [6, 7, 8] 17 ''' 18 19 # format() #格式化輸出字符串,format(value, format_spec)實質上是調用了value的__format__(format_spec)方法 20 ''' 21 "I am {0}, I like {1}!".format("wang", "moon") 22 "I am {}, I like {}!".format("wang", "moon") 23 "I am {name}, I like {msg}!".format(name = "wang", msg ="moon") 24 ''' 25 26 # input() #獲取用戶輸入內容 27 # open() 打開文件 28 # print() 輸出函數 29 30 # zip() 拉鍊函數將對象逐一配對 31 # s='helloo' 32 # l=[1,2,3,4,5] 33 # 34 # z=zip(s,l) 35 # print(z) 36 # for i in z: 37 # print(i) 38 39 40 # import time 41 # m=__import__('time') #以字符串的形式導入模塊 42 # m.sleep(3000) 43 44 ''' 45 map(function, iterable,...) 46 對於參數iterable中的每一個元素都應用fuction函數,並將結果做爲列表返回。 47 若是有多個iterable參數,那麼fuction函數必須接收多個參數,這些iterable中相同索引處的元素將並行的做爲function函數的參數。 48 若是一個iterable中元素的個數比其餘少,那麼將用None來擴展改iterable使元素個數一致。 49 若是有多個iterable且function爲None,map()將返回由元組組成的列表,每一個元組包含全部iterable中對應索引處值。 50 參數iterable必須是一個序列或任何可遍歷對象,函數返回的每每是一個列表(list)。 51 52 li = [1,2,3] 53 data = map(lambda x :x*100,li) 54 print(type(data)) 55 data = list(data) 56 print(data) 57 58 運行結果: 59 60 <class 'map'> 61 [100, 200, 300] 62 '''
十、面向對象使用函數
super(), isinstance(), issubclass(), classmethod(), staticmethod(), proerty(), delatter(), hasattr(), getattr(), setattr()
1 #super() 調用父類的方法 2 3 # isinstance() 檢查對象是不是類的對象,返回True或False 4 # issubclass() 檢查一個類是不是另外一個類的子類。返回True或False 5 6 7 # classmethod() # 用來指定一個方法爲類的方法,由類直接調用執行,只有一個cls參數,執行雷的方法時,自動將調用該方法的類賦值給cls.沒有此參數指定的類的方法爲實例方法 8 # staticmethod 9 # property 10 11 # delattr() # 刪除對象的屬性 12 # hasattr 13 ''' 14 hasattr(object,name) 15 判斷對象object是否包含名爲name的特性(hasattr是經過調用getattr(object,name))是否拋出異常來實現的。 16 參數object:對象 17 參數name:特性名稱 18 >>> hasattr(list, 'append') 19 True 20 >>> hasattr(list, 'add') 21 False 22 ''' 23 #getattr() 獲取對象的屬性 24 #setattr() 與getattr()相對應