日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python装饰器、生成器、内置函数、Json-Day05

發布時間:2025/3/15 python 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python装饰器、生成器、内置函数、Json-Day05 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?裝飾器

裝飾器本質上就是一個python函數,它可以讓其他函數在不需要做任何代碼變動的前提下增加額外功能,裝飾器的返回值也是一個函數對象。它經常用于有切面需求的場景,比如:插入日志、性能測試、事務處理、緩存、權限校驗等場景。裝飾器是解決這類問題的絕佳設計,有了裝飾器,我們就可以抽離大量與函數功能本身無關的雷同代碼并繼續重用。概括講,裝飾器的作用就是為依據存在的對象添加額外的功能。

定義:本質是函數,(裝飾其他函數)就是為其他函數添加附加功能 原則:
  • 不能修改被裝飾的函數的源代碼( 再不修改被裝飾函數源代碼的情況下為其添加功能)
  • 不能修改被裝飾的函數的調用方式
實現裝飾器功能知識儲備:
  • 函數既“變量”?
    • 函數的參數可以接收變量,也可以接受函數,這里引用函數即變量的概念

在python里面函數就是一個變量,函數名就是一個變量,這個函數名里面存的是這個函數的內存地址,它把函數體放到內存里,在調用的時候從函數名里面的這個內存地址找到函數體然后運行這個函數。前面的博客說函數的時候,說過函數名后面加上小括號就是調用這個函數,如果只寫這個函數名的話,打印一下就是這個函數的內存地址。

1 def test(): 2 print('Hello Word') 3 4 5 print(test) # 打印函數的內存地址 #<function test at 0x100662e18> 6 test() # 調用函數
  • 高階函數
    • 把一個函數名當做實參傳給另外一個函數
    • 返回值中包含函數名(不修改函數的調用方式) *是不是不理解很懵逼,沒事,一會用到*
    • 當傳遞函數作為變量時,被稱為高階函數?
1 import time 2 def bar(): 3 time.sleep(3) 4 print('in the bar !!') 5 6 def test1(func): 7 start_tiem = time.time() 8 func()# run bar() 9 stop_time = time.time() 10 print('the func run time is %s' %(stop_time-start_tiem)) 11 test1(bar)

強行插入知識點: 嵌套函數

1 def fun(): 2 print('in fun ') 3 def bar(): #函數的嵌套 4 print('in the bar ') 5 bar() 6 fun() 7 #--------------------------# 8 name = "Baylor" 9 def change_name(): 10 11 name = "Baylor2" 12 def change_name2(): 13 name = "Baylor3" 14 print("第3層打", name) 15 16 change_name2() # 調用內層函數 17 print("第2層打印", name) 18 19 change_name() 20 print("最外層打印", name)

嵌套函數中的作用域順序-由內而外的尋找符合要求的參數

第一個裝飾器

但每一次都需要從新對 test1 進行函數賦值,我們只需要通過裝飾器的特殊書寫方式,在需要增加新功能的函數上增加“@裝飾器函數名”就可以完成裝飾器的使用?

1 def timer(func): 2 def deco():#函數的嵌套 timer(test1) func = test1 3 start_time = time.time() 4 func() #run test1 5 stop_time = time.time() 6 print(' the func time is %s'%(stop_time - start_time)) 7 return deco #高階函數- 返回值中包含函數名 8 9 @timer # test1 = timer(test1) 10 def test1(): 11 time.sleep(3) 12 print('in the test1') 13 @timer 14 def test2(): 15 time.sleep(2) 16 print('in the test2') 17 18 #test1 = timer(test1) 19 test1()# --->deco 20 test2() 21 print(timer(test1)) #打印test1 內存地址

所以我們說:高階函數+嵌套函數 =>裝飾器 ,我們通過高階函數+函數嵌套實現了以上的裝飾器,他符合不改變調用方式,為函數增加新功能。

問題:被裝飾的函數如果有參數呢?

1 def w1(func): 2 def inner(arg): 3 # 驗證1 4 # 驗證2 5 # 驗證3 6 return func(arg) 7 return inner 8 9 @w1 10 def f1(arg): 11 print ('f1') 12 13 14 def w1(func): 15 def inner(arg1,arg2,arg3): 16 # 驗證1 17 # 驗證2 18 # 驗證3 19 return func(arg1,arg2,arg3) 20 return inner 21 22 @w1 23 def f1(arg1,arg2,arg3): 24 print ('f1')

問題:可以裝飾具有處理n個參數的函數的裝飾器?

1 def w1(func): 2 def inner(*args, **kwargs): 3 # 驗證1 4 # 驗證2 5 # 驗證3 6 print(*args,**kwargs) 7 8 return func(*args, **kwargs) 9 return inner 10 11 @w1 12 def f1(arg1, arg2, arg3): 13 print('f1') 14 15 f1(1,2,3)

?

如果要裝飾的函數帶有參數時,因為你也不知道到底被裝飾的函數會傳什么參數,所以可以使用可變參數和關鍵字參數來接收所有的參數

1 import time 2 def timer(func): 3 def deco(*args,**kwargs):#函數的嵌套 timer(test1) func = test1 4 start_time = time.time() 5 func(*args,**kwargs) #run test1 6 stop_time = time.time() 7 print(' the func time is %s'%(stop_time - start_time)) 8 return deco #高階函數 9 10 @timer # test1 = timer(test1) 11 def test1(): 12 time.sleep(3) 13 print('in the test1') 14 @timer # test2 = timer(test2) = deco test2(name) = deco(name) 15 def test2(name,arg): 16 time.sleep(2) 17 print('in the test2 %s %s',name,arg) 18 19 test1()# --->deco 20 test2('Baylor',28)

在函數的傳遞參數過程中,我們的裝飾器不能滿足帶參數的傳遞,以上,實現了當函數有參數傳遞的過程中也可以實現裝飾器的新功能

終極函數裝飾-補充知識

1 import time 2 user,passwd = 'jinyu','abc123' 3 def auth(auth_type): 4 def outer_wrapper(func): 5 print('auth func:',auth_type) 6 def wrapper(*args,**kwargs): 7 print('------',auth_type) 8 if auth_type =='local': 9 username = input('Username:') 10 password = input('Password') 11 if user == username and passwd == password: 12 13 print('\033[31;1mUser has password authentication\033[0m') 14 # res = func(*args,**kwargs) 15 res = func(*args,**kwargs) #1,2 16 print('-----afte authentication-----',res) 17 res.append(3) 18 print(res) 19 return res,'方法已運行完畢' # 結果 20 else: 21 print('\033[32;1m Invalid username or password\033[0m') 22 elif auth_type =='ldap': 23 print('哈哈哈哈哈哈!!!ldap') 24 return wrapper 25 return outer_wrapper 26 27 def index(): 28 print('welcome to index page!') 29 @auth(auth_type = 'local')#home = wraapper 30 def home(): 31 print('welcome to home page!') 32 return [1,2] 33 @auth(auth_type = 'ldap') 34 def bbs(): 35 print('welcome to bbs page!') 36 37 index() 38 home() 39 # bbs()

三層函數形成了終結裝飾器,通過裝飾器所傳的參數能夠進行裝飾器功能判斷,提供了更好的擴展性?

?列表生成式-作用:使代碼更加簡潔

1 a = [i*2 for i in range(10)] #列表生成式 3行代碼一行搞定 2 print(a) 3 4 a = [] 5 for i in range(10): 6 a.append(i*2) 7 print(a)

生成器

  • 只有在調用時才會生成相應的數據----生成器:你用到這個里面的數據的時候它才會生成,這樣就比較省內存,因為是需要這個值的時候,才會在內存里面產生
  • 只記錄當前位置,只有一個__next__()方法 2.7next()?
1 a =(i * 2 for i in range(10)) #如果要打印generator中的元素需要借助next方法 需要循環才能取出 2 # a =[i * 2 for i in range(10)] # list的元素我們可以一個個打印出, 3 print(a) #<generator object <genexpr> at 0x10228f2b0> 4 print(next(a)) 5 print(next(a)) 6 print(a.__next__())
7 print(a.__next__())

?小練習-斐波那契數列?

1 def fib(max): 2 n, a, b = 0, 0, 1 3 while n < max: 4 print(b) 5 a, b = b, a + b # t(b,a+b) a=t[0]-1 b=t[1]-2 a+b等同于 t的下標相加 6 n = n + 1 7 return 'done' # 無用 8 9 10 fib(10) 11 12 # 如果把這個改進成 yield 生成器,通過 __next__調用 只需要 把print(b) 改成 yield b 即可 13 temp = [] 14 15 16 def fib(max): 17 n, a, b = 0, 0, 1 18 while n < max: 19 yield b 20 a, b = b, a + b # t(b,a+b) a=t[0]-1 b=t[1]-2 a+b等同于 t的下標相加 21 n = n + 1 22 return 'done' # 無用 23 24 x = fib(10) 25 print(x) 26 print(x.__next__()) 27 print(x.__next__()) 28 print(x.__next__()) 29 print(x.__next__())?

匿名函數 ---也叫 lambda函數

1 #匿名函數就是不需要顯式的指定函數 2 3 # 這段代碼 4 def calc(n): 5 return n * n 6 7 print(calc(10)) 8 9 # 換成匿名函數 10 calc = lambda n: n * n 11 print(calc(10)) 12 #你也許會說,用上這個東西沒感覺有毛方便呀, 。。。。呵呵,如果是這么用,確實沒毛線改進,不過匿名函數主要是和其它函數搭配使用的呢,如下 13 #x=[1, 5, 7, 4, 8] 14 res = map(lambda x: x * 2, [1, 5, 7, 4, 8]) #map會根據提供的函數對指定序列做映射。 15 for i in res: 16 print(i)
#匿名函數只能處理比較簡單的處理邏輯,只能寫簡單的表達式,不能寫循環 判斷,比如三元運算符

?json 處理

json是一種所有語言中都通用的key-value數據結構的數據類型,很像python中的字典,json處理使用json模塊,json模塊有下面常用的方法:

1 import json 2 3 dic = {"name": "niuniu", "age": 18} 4 print(json.dumps(dic)) # 把字典轉成json串 5 fj = open('a.json', 'w') 6 print(json.dump(dic, fj)) # 把字典轉換成的json串寫到一個文件里面 7 s_json = '{"name":"niuniu","age":20,"status":true}' 8 print(json.loads(s_json)) # 把json串轉換成字典 9 10 # 先創建b.json文件 運行運行此代碼*{"name": "chenjianguo", "age": 18}* 11 fr = open('b.json', 'r') 12 print(json.load(fr)) # 從文件中讀取json數據,然后轉成字

首先說明基本功能:
  • dumps是將dict轉化成str格式,loads是將str轉化成dict格式。
  • dump和load也是類似的功能,只是與文件操作結合起來了。
  • dump 是把字典轉成son串格式寫 ? load是把json串轉成字典讀-(json必須雙引號)

  內置函數詳細介紹?https://docs.python.org/3/library/functions.html?highlight=built#ord?

資料補充

生成器并行

1 import time 2 def consumer(name): 3 print('%s 我準備吃包子了'%name) 4 while True: 5 baozi = yield #保存當前狀態返回, 6 print('包子[%s]來了,被[%s]吃了'%(baozi,name)) 7 # c = consumer('houzi') 8 # c.__next__() 9 #b = '韭菜餡' 10 #c.send(b) # 調用yield 并傳值 11 #c.__next__() 12 def producer(name): 13 c = consumer('A') #生成 14 c2 = consumer('B') 15 c.__next__() 16 c2.__next__() 17 print('開始準備做包子了。。。。。。') 18 for i in range(10): 19 time.sleep(1) 20 print('做了2個包子!!!!') 21 c.send(i) 22 c2.send(i) 23 24 producer('houzi')

?使用類來寫裝飾器-強勢插入新知識

分享一下,需要用類里面的__call__方法,__call__方法就是可以把這個實例當成一個函數來調用,如果正常使用類里面的方法的話,實例方法要先實例化類,然后才能調用,靜態方法、類方法則需要用類名或者實例化之后的對象來調用,而實例化之后的這個對象,是不能被調用的,__call__方法就是把這個實例變成一個可以調用的對象,也就是說實例化之后,這個對象就可以和一個普通函數一樣被調用。

1 class Foo: 2 def __call__(self, *args, **kwargs): 3 print('call....') 4 def test(self):# 5 print('test....') 6 if __name__ == '__main__': 7 t = Foo()#實例化類 8 t.test()#正常調用實例方法 9 t()#直接調用實例化之后的對象
理解了上面的之后,就可以使用class來寫一個裝飾器了,計算程序的運行時間,當然思想和以前用函數寫裝飾器是一樣的 1 class Fuck(object): 2 def __init__(self, func): 3 self.func = func 4 def __call__(self, *args, **kwargs): 5 import time 6 start_time = time.time() 7 res = self.func(*args, **kwargs) 8 end_time = time.time() 9 print('the function "%s" run time is %s' % (self.func.__name__, 10 (end_time - start_time))) 11 return res 12 @Fuck 13 def run(name): 14 import time 15 time.sleep(1) 16 return 'sb_%s' % name 17 print(run('hyf'))

?

轉載于:https://www.cnblogs.com/Baylor-Chen/p/9046641.html

總結

以上是生活随笔為你收集整理的Python装饰器、生成器、内置函数、Json-Day05的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。