python反射、闭包、装饰器_python之闭包、装饰器、生成器、反射
1. 函數的作用域
1.在函數定義時候就固定,與調用位置無關,在調用的時候返回到函數定義的位置
x=1 #全局作用
def f1(): #整個f1函數是定義階段
deff2():print(x)returnf2deffoo(func):
x=3func()#func()調用階段
x=200 #這樣定義x又變成全局了
foo(f1()) #執行foo(f1()) 返回到F1函數里找x所以打印是1不是3
生成器
2.名稱空間
內置名稱空間:在python解釋器啟動產生的空間,簡單理解就是python自帶的方法比如:max()len()
全局名稱空間 :在全局定義的好的名稱空間,文件級別的產生的 比如:
x=1 #全局作用
deftest():
x=2 #局部作用print(x)
test()
if x=1 y=2#全局作用
#在執行test()調用的時候先加載內置查找有沒有test這個內置函數,如果去全局里查找test這個函數方法,最后局部
局部名稱空間:在調用函數時候產生局部名稱空間 y=2,在調用teset()立馬產生了局部作用空間
nonlocal x 函數正上方的x的變量
global x 改成全局的變量
3.閉包函數
閉包函數的作用主要在與裝飾器
函數式編程里面閉包只是給函數捆綁死一個值或者狀態
1.定義在函數內部的函數
2. 包含對外部作用域名字的引用,而不是對全局作用域名字的引用
3.該內部函數就稱為閉包函數
importrequests#第一種傳參閉包
defre(func):defget():returnrequests.get(func).textreturnget
baidu=re('http://www.baidu.com')
baidu1=re('http://www.souhu.com')print(baidu())#第二種自定義固定值閉包函數
deftest():
url='http://www.baidu.com'
defgett(): #gett()是閉合函數外面包裹這個urlreturnrequests.get(url).textreturngett
func=test()print(func())
def ff():
url=‘nq.com’
func() #此時的func已經一種狀態就是url這個百度地址不會
ff() #得到的結果是url='http://www.baidu.com'
4.裝飾器
裝飾器的定義:1.在不變動主功能函數的前提下,為其添加上新的功能或者狀態。
例:比如抓數據時候,我們需要添加計時器,顯示抓取用了多少時間,
寫一個te函數是計時器功能,這樣可以給爬取baidu、搜狐網站添加上這個計時器。
第一種裝飾器寫法,其實是給閉包函數添加了一個功能
importrequests
improt time#第一種傳參閉包,這里當主功能函數
defre(func):defget():returnrequests.get(func).textreturnget
baidu=re('http://www.baidu.com')
baidu1=re('http://www.souhu.com')print(baidu())#裝飾器,給獲取百度數據添的用時
defte(func):deftimer():
start=time.time()
func()
stop=time.time()print("獲取數據的時間%s"%(stop-start))returntimer
baidu=te(baidu)
baidu()
第二種寫法
這種方法適合用@裝飾器函數名稱,上面例子是閉包函數,已經閉包了是不可以種@的來裝飾建議使用? 函數調用方式
n是表示給傳參的函數,以防萬一最要用*args,**kwargs的方式
1 importpsutil2 defcount(func):3 deftimer():4 fu=psutil.cpu_count()5 print(fu)6 func(1)7 returntimer8
9
10 #查看cpu使用情況的一個函數
11 @count12 defmain(n):13 res=psutil.cpu_times()14 print(res)15 print(n)16
17 #查看Process的一個函數n
18 @count19 deftest(t):20 fl=psutil.Process21 print(fl)22 print(t)23
24
25 test()26 main()
View Code
裝飾器的細節問題:
from functools import wraps 在裝飾器中添加顯示備注信息,如下代碼
importpsutilfrom functools importwrapsdefcount(func):
@wraps(func) #這里需要添加wraps這個裝飾器deftimer():
fu=psutil.cpu_count()print(fu)
func(1)returntimer#查看cpu使用情況的一個函數
@countdefmain(n):'''這個是mian函數的'''res=psutil.cpu_times()print(res)print(n)
#return 123 如果函數里有return 打印這個函數結果時候顯示空 因為,main顯示已經被conunt函數裝飾了,所以要在timer里面retrun才對print(main.__doc__) #這里是打印上面的備注信息
生成器
生成器:不斷調用和返回值,生成器
迭代器:可以被next()函數調用并不斷返回下一個值的對象稱為迭代器,可以直接作用于for循環的對象統稱為可迭代對象
# def Pycharm(name):
# food_list=[]
# food= yieldfood_list
# print("%s想吃%s" %(name, food))
# food_list.append(food)
# print(food_list)
#
#
# res= Pycharm('alex')
# next(res) #next 會停留在 food=yield這里,send傳送后繼續執行下面的內容
# res.send('fangfood')
python之反射
反射即想到4個內置函數分別為:getattr、hasattr、setattr、delattr ?獲取成員、檢查成員、設置成員、刪除成員下面逐一介紹先看例子
它的核心本質其實就是利用字符串的形式去對象(模塊)中操作(查找/獲取/刪除/添加)成員,一種基于字符串的事件驅動
classfunc():def __init__(self):
self.teacher='teacher'self.student='student'self.age='ee'self.name='name'
deftest01(self):print('反射機智顯示test01功能%s' %self.teacher)deftest02(self):print('反射機智顯示test02功能%s' %self.student)
func=func()defrun():''':return:通過res用戶輸入相對應的變量、函數方法
通過反射機制來判斷、增刪添改'''res=input('>>我想執行里面的函數:').strip()
hasa=hasattr(func,res) #hasattr 可以判斷func類中是否存在res傳入的變量或者函數方法
res=getattr(func,res,'not find') #getattr 可以獲取傳入方法或者函數的執行結果,
#得到是內存地址需要通過res()來展示內容
#not find意思 如果沒有找到相對應的變量和函數 通過print(res())來打印出notfind
#print(res())
tom=setattr(func,res,18) #setattr 可以修改傳入變量的結果 比如self age=17 通過setattr可以修改成18
print(func.age)
delattr(func,'age') #delattr 刪除age這個變量
print(func.age)#setattr(func,res,18)
run()
總結
以上是生活随笔為你收集整理的python反射、闭包、装饰器_python之闭包、装饰器、生成器、反射的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 减肥能吃葡萄吗
- 下一篇: 不控制饮食只运动能减肥吗
