函數進階---作用域、閉包、裝飾器
阿新 • • 發佈:2018-05-18
閉包 查看 就是 喜歡 name 應該 tro 變量 擴展
名稱空間
名稱空間指存放名字的地方
名稱空間分為三種:
- locals:函數內部的名稱空間,包括局部變量與形參
- globals:全局變量,函數模塊定義所在模塊的空間
- builtins 內置模塊的名稱空間
不同變量的作用域不同就是由這個變量的所在變名空間決定的
作用域:
全局範圍:全局存活,在全局生效
局部範圍:局部存活,在局部生效
查看作用域的方法:locals(),globals()
名稱空間的查找順序
LEGB查找順序:locals-->enclosing function-->globals-->builtins - locals:指局部名稱空間
- enclosing function:指外部嵌套函數的名稱空間
- globals:全局變量,函數模塊定義所在的名稱空間
- builtins:內置模塊的名稱空間
閉包
閉包是指內部函數包含對外部作用域而非全局作用域的引用,即:A函數裏再定義一個b函數(嵌套函數)而B函數裏調了A函數的變量,而A函數返回值是B函數的引用,這樣就構成了閉包
def fun():
name = ‘ab‘
def fun1():
print(‘fun1‘,name)
return fun1
a = fun()
a()
閉包的意義:返回的函數對象,不僅僅是一個函數對象,在該函數外還包裹了一層作用域,這使得,該函數無論在何處調用,優先使用自己外層包裹的作用域
裝飾器
什麽是裝飾器?
裝飾器他人的器具,本身可以是任意可調用對象,被裝飾者也可以是任意可調用對象。
強調裝飾器的原則:
- 不修改被裝飾對象的源代碼
- 不修改被裝飾對象的調用方式
裝飾器的目標:在遵循1和2的前提下,為被裝飾對象添加上新功能
程序員應該尊守封閉,開發原則!
- 封閉:已實現的功能代碼塊不應該被修改
- 開放:對現有功能的擴展開放
代碼:
flag = False def login(fun): def ineer(*args,**kwargs): username = ‘alex‘ password = ‘123‘ global flag if flag == False: _username = input(‘user:‘).strip() _passwd = input(‘passwd:‘).strip() if _username == username and _passwd == password: print(‘登陸成功‘) flag = True else: print(‘登陸失敗‘) if flag == True: return fun(*args,**kwargs) return ineer def home(): print("---首頁----") @login def america(): #login() #執行前加上驗證 print(‘用戶已登陸,不需要驗證‘) print("----歐美專區----") def japan(): print("----日韓專區----") @login #想當於henan = login(henan) def henan(style): ‘‘‘ :param style: 喜歡看什麽類型的,就傳進來 :return: ‘‘‘ #login() #執行前加上驗證 print("----河南專區----") henan(‘3p‘) #實際調用的是inner函數 america()
函數進階---作用域、閉包、裝飾器