名称空间与作用域、闭包函数、 装饰器
1 名稱空間與作用域
2 ?閉包函數(shù)
3 ?裝飾器
6.7 名稱空間與作用域
內(nèi)置名稱空間:
存放的是:內(nèi)置的名字與值的綁定關(guān)系
生效:python解釋器啟動
失效:Python解釋器關(guān)閉
全局名稱空間:
存放的是:文件級別定義的名字與值的綁定
生效:執(zhí)行python文件時,將該文件級別定義的名字與值的綁定關(guān)系存放起來
失效:文件執(zhí)行完畢
局部名稱空間:
存放的是:函數(shù)內(nèi)部定義的名字與值的綁定關(guān)系
生效:調(diào)用函數(shù)時,臨時生效
失效:函數(shù)調(diào)用結(jié)束
#python test.py
#1、python解釋器先啟動,因而首先加載的是:內(nèi)置名稱空間
#2、執(zhí)行test.py文件,然后以文件為基礎(chǔ),加載全局名稱空間
#3、在執(zhí)行文件的過程中如果調(diào)用函數(shù),則臨時產(chǎn)生局部名稱空間
加載順序:內(nèi)置---》全局----》局部名稱空間
訪問名字的順序:局部名稱空間===》全局----》內(nèi)置
x=1 #全局變量 print(x) print(max) #內(nèi)置變量 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()全局作用域(全局范圍):內(nèi)置名稱空間與全局名稱空間的名字,全局存活,全局有效,globals()
局部作用域(局部范圍):局部名稱空間的名字,臨時存活,局部有效,locals()
查看作用域:globals(),locals()
LEGB 代表名字查找順序: locals -> enclosing function -> globals -> __builtins__
locals 是函數(shù)內(nèi)的名字空間,包括局部變量和形參
enclosing 外部嵌套函數(shù)的名字空間(閉包中常見) #f2()上有f1(),下有f3()
globals 全局變量,函數(shù)定義所在模塊的名字空間
builtins 內(nèi)置模塊的名字空間
global: 關(guān)鍵字用來在函數(shù)或其他局部作用域中使用全局變量。但是如果不修改全局變量也可以不使用global關(guān)鍵字。
x=100 def func():global x #在函數(shù)內(nèi)調(diào)用全局變量x=1func() print(x)nonlocal:關(guān)鍵字用來在函數(shù)或其他作用域中使用外層(非全局)變量。函 數(shù)內(nèi)部一層一層往上找,沒有則報錯
x='global' def f1():x=1def f2():nonlocal x #調(diào)用外層(非全局)變量x=0f2()print('===f1 innter--->',x)f1() print(x)強(qiáng)調(diào)兩點(diǎn):
1、打破函數(shù)層級限制來調(diào)用函數(shù)
2、函數(shù)的作用域關(guān)系是在函數(shù)定義階段就已經(jīng)固定了,與調(diào)用位置無關(guān)
x=1 def outter():x=2def inner():print('inner',x)return innerf=outter() def bar():x=3f() bar() # 執(zhí)行結(jié)果:inner 26.8 閉包函數(shù)
閉包函數(shù):
1 定義在函數(shù)內(nèi)部的函數(shù)
2 該函數(shù)的函數(shù)體代碼包含對外部作用域(而不是全局作用域)名字的引用
3 通常將閉包函數(shù)用return返回,然后可以在任意使用
z=1 def outer():x=1y=2def inner(): #閉包函數(shù)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()應(yīng)用:
爬頁面:閉包函數(shù)為我們提供了一種新的為函數(shù)傳參的方式
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 無參裝飾器
開放封閉原則:對擴(kuò)展開放,對修改是封閉
裝飾器:裝飾它人的,器指的是任意可調(diào)用對象,現(xiàn)在的場景裝飾器-》函數(shù),被裝飾的對象也是-》函數(shù)
原則:1、不修改被裝飾對象的源代碼
? ? ? ? ? ? 2、不修改被裝飾對象的調(diào)用方式
裝飾器的目的:在遵循1,2的前提下為被裝飾對象添加上新功能
# 錯誤的示范,改變了調(diào)用方式 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()裝飾器語法:在被裝飾對象正上方單獨(dú)一行寫上,@裝飾器名
#改進(jìn)一: 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)#改進(jìn)二: 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補(bǔ)充
wraps: 讓被裝飾的函數(shù),使用help()是看到的信息也是被裝飾函數(shù)的幫助信息。
from functools import wraps #導(dǎo)入模塊 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 函數(shù)。。。。。''' #index函數(shù)的幫助信息time.sleep(1)print('welecome %s to index' %name)return 1111 # res=index('egon') # print(res)print(help(index))?
轉(zhuǎn)載于:https://www.cnblogs.com/snailgirl/p/8125021.html
總結(jié)
以上是生活随笔為你收集整理的名称空间与作用域、闭包函数、 装饰器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssdb的网络模型
- 下一篇: Controller 返回图片请求