python學習之函數學習進階
阿新 • • 發佈:2017-05-22
python學習之函數進階
1.名稱空間 python有三種名稱空間 內置名稱空間: 隨著python解釋器的啟動而產生 print(sum) print(max) 全局名稱空間: 文件的執行會產生全局名稱空間,指的是文件級別的定義名字都會放入該空間 x = 11 if x == 11: print(x) 局部名稱空間: 調用函數時會產生局部名稱空間,只在函數調用時臨時綁定,調用結束時解綁 x = 1000 def foo(): x = 1 print(x) foo() print(x) 作用域: 1.全局作用域: 內置名稱空間,全局名稱空間,全局有效,在任何位置都能被訪問到, 除非del刪除,否則存活到文件結束。 2.局部作用域: 局部名稱空間,局部有效,只能在局部範圍調用,調用結束失效。 名字的查找順序: 局部名稱空間-->全局名稱空間-->內置名稱空間 x = 1000 def func(): x = 2 print(locals()) #locals()查看局部作用域內的名字 print(globals()) #globals()查看全局作用域內的名字 2.函數對象 1.可以被引用 2.可以當作參數傳遞 3.返回值可以是函數 4.可以當作容器類型的元素 例子: def foo(): print("from foo") func = foo print(foo) print(func) foo() func() def foo(): print("from foo") def bar(func): print(func) func() bar(foo) def foo(): print("from foo") dic = {‘func‘: foo} print(dic[‘func‘]) dic[‘func‘]() 3.閉包函數 閉包: 1.定義在內部函數 2.包含對外部作用域而非全局作用域的引用 該內部函數就稱作閉包函數 例子: def f1(): x = 1 def f2(): #f2稱作閉包函數 print(x) return f2 f = f1() print(f) #打印f2函數的內存地址 f() #打印1 例子: from urllib.request import urlopen def index(url): def get(): return urlopen(url).read() return get oldboy = index(‘http://www.baidu.com‘) print(oldboy().decode(‘utf-8‘)) print(oldboy.__closure__[0].cell_contents) #打印外部引用而非全局引用對象 4.裝飾器 修飾其他對象的工具,修飾添加功能,工具指的是函數。 裝飾器本身是任何可調用對象,被裝飾的對象也可以是任何可調用的對象。 為什麽要用裝飾器? 開放封閉原則,對修改是封閉的,對擴展是開放的。 裝飾器就是為了在不修改被裝飾對象源代碼以及調用方式的前提下,為其添加新功能 裝飾器相當於閉包的實現 例子: import time def timmer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print("run time is {0}".format(stop_time - start_time)) return wrapper @timmer #相當於index = timmer(index) def index(): time.sleep(3) print("welcome to index") return 1 index() #其實相當於執行了timmer(index) 例子: import time def timmer(func): def wrapper(*args, **kwargs): start_time = time.time() res = func(*args, **kwargs) stop_time = time.time() print("run time is {0}".format(stop_time - start_time)) return wrapper def index(): time.sleep(3) print("welcome to index") f = timmer(index) print(f) f() #f()<=====>wrapper() 認證用戶登錄 login_user = {‘user‘: None, ‘status‘: False} def auth(func): def wrapper(*args, **kwargs): if login_user[‘user‘] and login_user[‘status‘]: res = func(*args, **kwargs) return res else: name = input("請輸入姓名:") passwd = input("請輸入密碼:") if name == "hyh" and passwd == "123": login_user[‘user‘] = "hyh" login_user[‘status‘] = True print("\033[45mlogin successful\033[0m") res = func(*args, **kwargs) return res else: print("\033[45mlogin err\033[0m") return wrapper @auth def index(): print("welcome to index page") @auth def home(name): print("%s welcome to home page" % (name)) index() home("hyh") 5.叠代器 叠代器的概念: 重復上一次叠代的結果為下一次叠代的初始值,重復的過程稱為叠代, 每次重復即一次叠代 為什麽要有叠代器? 對於沒有索引的數據類型,必須提供一種不依賴索引的叠代方式 可叠代對象: 內置__iter__方法的都是可叠代對象 [1,2].__iter__() ‘hello‘.__iter__() (1,2).__iter__() {"a":1, "b": 2}.__iter__() {1,2,3}.__iter__() 叠代器: 執行__iter__()方法,得到的結果就是叠代器,叠代器有__next__()方法 i = [1,2,3].__iter__() print(i.__next__()) #打印1 print(i.__next__()) #打印2 print(i.__next__()) #打印3 print(i.__next__()) #拋出異常 i__iter__() <==>iter(i) i__next__() <==>next(i) 如何判斷一個對象是可叠代對象,還是叠代器對象 from collections import Iterable, Iterator print(isinstance(‘abc‘,Iterable)) print(isinstance([],Iterable)) print(isinstance((),Iterable)) print(isinstance({‘a‘:1},Iterable)) print(isinstance({1,2},Iterable)) f=open(‘a.txt‘,‘w‘) f.__iter__() print(isinstance(f,Iterable)) #只有文件是叠代器對象 可叠代對象:只有__iter__方法,執行該方法得到的叠代器對象 叠代協議: 對象有__next__ 對象有__iter__,對於叠代器對象來說,執行__iter__方法,得到的結果仍然是它本身 叠代器的優點和缺點 優點: 1.提供了一種不依賴下標的叠代方式 2.就跌叠代器本身來說,更節省內存 缺點: 1. 無法獲取叠代器對象的長度 2. 不如序列類型取值靈活,是一次性的,只能往後取值,不能往前退
本文出自 “linux技術” 博客,請務必保留此出處http://xiaojishu.blog.51cto.com/4278020/1928374
python學習之函數學習進階