名称空间与作用域、闭包函数、 装饰器
1 名稱空間與作用域
2 ?閉包函數
3 ?裝飾器
6.7 名稱空間與作用域
內置名稱空間:
存放的是:內置的名字與值的綁定關系
生效:python解釋器啟動
失效:Python解釋器關閉
全局名稱空間:
存放的是:文件級別定義的名字與值的綁定
生效:執行python文件時,將該文件級別定義的名字與值的綁定關系存放起來
失效:文件執行完畢
局部名稱空間:
存放的是:函數內部定義的名字與值的綁定關系
生效:調用函數時,臨時生效
失效:函數調用結束
#python test.py
#1、python解釋器先啟動,因而首先加載的是:內置名稱空間
#2、執行test.py文件,然后以文件為基礎,加載全局名稱空間
#3、在執行文件的過程中如果調用函數,則臨時產生局部名稱空間
加載順序:內置---》全局----》局部名稱空間
訪問名字的順序:局部名稱空間===》全局----》內置
x=1 #全局變量 print(x) print(max) #內置變量 max=2 #全局變量 def func():# max=1 #局部變量print(max) func()x='gobal' #全局變量 def f1():# x=1 #局部變量def f2():# x=2 #局部變量def f3():# x=3 #局部變量print(x)f3()f2() f1()全局作用域(全局范圍):內置名稱空間與全局名稱空間的名字,全局存活,全局有效,globals()
局部作用域(局部范圍):局部名稱空間的名字,臨時存活,局部有效,locals()
查看作用域:globals(),locals()
LEGB 代表名字查找順序: locals -> enclosing function -> globals -> __builtins__
locals 是函數內的名字空間,包括局部變量和形參
enclosing 外部嵌套函數的名字空間(閉包中常見) #f2()上有f1(),下有f3()
globals 全局變量,函數定義所在模塊的名字空間
builtins 內置模塊的名字空間
global: 關鍵字用來在函數或其他局部作用域中使用全局變量。但是如果不修改全局變量也可以不使用global關鍵字。
x=100 def func():global x #在函數內調用全局變量x=1func() print(x)nonlocal:關鍵字用來在函數或其他作用域中使用外層(非全局)變量。函 數內部一層一層往上找,沒有則報錯
x='global' def f1():x=1def f2():nonlocal x #調用外層(非全局)變量x=0f2()print('===f1 innter--->',x)f1() print(x)強調兩點:
1、打破函數層級限制來調用函數
2、函數的作用域關系是在函數定義階段就已經固定了,與調用位置無關
x=1 def outter():x=2def inner():print('inner',x)return innerf=outter() def bar():x=3f() bar() # 執行結果:inner 26.8 閉包函數
閉包函數:
1 定義在函數內部的函數
2 該函數的函數體代碼包含對外部作用域(而不是全局作用域)名字的引用
3 通常將閉包函數用return返回,然后可以在任意使用
z=1 def outer():x=1y=2def inner(): #閉包函數print(x,y)return innerf=outer() print(f.__closure__[0].cell_contents) # 1 print(f.__closure__[1].cell_contents) # 2 print(f.__closure__) #(<cell at 0x00000000026D65B8: int object at 0x0000000054FBC6B0>, <cell at 0x00000000026D65E8: int object at 0x0000000054FBC6D0>)def bar():x=111121y=2222f() bar()應用:
爬頁面:閉包函數為我們提供了一種新的為函數傳參的方式
import requests #pip3 install requests def outter(url):# url = 'https://www.baidu.com'def get():response=requests.get(url)if response.status_code == 200:print(len(response.text))return getbaidu=outter('https://www.baidu.com') python=outter('https://www.python.org') baidu() python() baidu ()6.9 裝飾器
6.9.1 無參裝飾器
開放封閉原則:對擴展開放,對修改是封閉
裝飾器:裝飾它人的,器指的是任意可調用對象,現在的場景裝飾器-》函數,被裝飾的對象也是-》函數
原則:1、不修改被裝飾對象的源代碼
? ? ? ? ? ? 2、不修改被裝飾對象的調用方式
裝飾器的目的:在遵循1,2的前提下為被裝飾對象添加上新功能
# 錯誤的示范,改變了調用方式 import time def index():time.sleep(3)print('welecome to index')def timmer(func):start=time.time()func()stop=time.time()print('run time is %s' %(stop-start))timmer(index)?
# 正確但不完善 import time def index():time.sleep(3)print('welecome to index')def timmer(func):# func=index #最原始的indexdef inner():start=time.time()func() #最原始的indexstop=time.time()print('run time is %s' %(stop-start))return innerindex=timmer(index) #index=inner # print(f) index() #inner()裝飾器語法:在被裝飾對象正上方單獨一行寫上,@裝飾器名
#改進一: import time def timmer(func):def inner():start=time.time()res=func()stop=time.time()print('run time is %s' %(stop-start))return resreturn inner@timmer #index=timmer(index) def index():time.sleep(1)print('welecome to index')return 1111res=index() #res=inner() print(res)#改進二: import time def timmer(func):def inner(*args,**kwargs):start=time.time()res=func(*args,**kwargs)stop=time.time()print('run time is %s' %(stop-start))return resreturn inner@timmer #index=timmer(index) def index(name):time.sleep(1)print('welecome %s to index' %name)return 1111 res=index('egon') #res=inner('egon') print(res)6.9.2 有參裝飾器
import time def auth2(engine='file'):def auth(func): # func=indexdef inner(*args,**kwargs):if engine == 'file':name=input('name>>: ').strip()password=input('password>>: ').strip()if name == 'egon' and password == '123':print('login successful')return func(*args,**kwargs)else:print('login err')elif engine == 'mysql':print('mysql auth')elif engine == 'ldap':print('ldap auth')else:print('engin not exists')return innerreturn auth@auth2(engine='mysql') #@auth #index=auth(index) #index=inner def index(name):time.sleep(1)print('welecome %s to index' %name)return 1111res=index('egon') #res=inner('egon')print(res)6.9.3 并列多個裝飾器
import time def timmer(func):def inner(*args,**kwargs):start=time.time()res=func(*args,**kwargs)stop=time.time()print('run time is %s' %(stop-start))return resreturn innerdef auth2(engine='file'):def auth(func): # func=indexdef inner(*args,**kwargs):if engine == 'file':name=input('name>>: ').strip()password=input('password>>: ').strip()if name == 'egon' and password == '123':print('login successful')return func(*args,**kwargs)else:print('login err')elif engine == 'mysql':print('mysql auth')elif engine == 'ldap':print('ldap auth')else:print('engin not exists')return innerreturn auth@auth2(engine='file') #多個裝飾器 @timmer def index(name):time.sleep(1)print('welecome %s to index' %name)return 1111res=index('egon') print(res)6.9.4 wraps補充
wraps: 讓被裝飾的函數,使用help()是看到的信息也是被裝飾函數的幫助信息。
from functools import wraps #導入模塊 import timedef timmer(func):@wraps(func) #使用 wraps裝飾def inner(*args,**kwargs):start=time.time()res=func(*args,**kwargs)stop=time.time()print('run time is %s' %(stop-start))return res# inner.__doc__=func.__doc__# inner.__name__=func.__name__return inner@timmer def index(name): #index=inner'''index 函數。。。。。''' #index函數的幫助信息time.sleep(1)print('welecome %s to index' %name)return 1111 # res=index('egon') # print(res)print(help(index))?
轉載于:https://www.cnblogs.com/snailgirl/p/8125021.html
總結
以上是生活随笔為你收集整理的名称空间与作用域、闭包函数、 装饰器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssdb的网络模型
- 下一篇: Controller 返回图片请求