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

歡迎訪問 生活随笔!

生活随笔

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

python

Python中的装饰器,迭代器,生成器

發布時間:2023/12/31 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python中的装饰器,迭代器,生成器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 裝飾器

  • 裝飾器他人的器具,本身可以是任意可調用對象,被裝飾者也可以是任意可調用對象。
  • 強調裝飾器的原則:1 不修改被裝飾對象的源代碼 2 不修改被裝飾對象的調用方式
  • 裝飾器的目標:在遵循1和2的前提下,為被裝飾對象添加上新功能
  • 開放封閉原則:對修改封閉,對擴展開放
import timedef timmer(fun):start_time=time.time()fun()end_time=time.time()def fun1():print("in func1")timmer(fun1) #改變了原先函數的執行
  • 就要用閉包來包裝此函數

import timedef timmer(fun):def inner():start_time=time.time()fun()end_time=time.time()print("run in {} time {}".format(fun,end_time-start_time))return inner #實際上是把函數名字傳遞給timmer,timmer執行,之所以返回inner是因為inner在全局不可以被調用def fun1():print("in func1")print(timmer(fun1)) #可以運行,其實就是執行Inner,目的就是在全局可以調用, fun1=timmer(fun1) #函數本身就是變量,變量值互換 fun1()
  • 這樣最基本的裝飾器就完成了,Python為我們提供了語法糖,一個完整的裝飾器如下:會允許函數傳參并且返回值不變

import timedef timmer(fun):def inner(*args,**kwargs):start_time=time.time()ret = fun(*args,**kwargs)end_time=time.time()print("run in {} time {}".format(fun,end_time-start_time))return retreturn inner #實際上是把函數名字傳遞給timmer,timmer執行,之所以返回inner是因為inner在全局不可以被調用@timmer def fun1(num):print("in func1 {}".format(num))return 123# print(timmer(fun1)) #可以運行,其實就是執行Inner,目的就是在全局可以調用, # fun1=timmer(fun1) #函數本身就是變量,變量值互換 print(fun1(1))
  • 這樣可以修飾多個函數,但是要批量更改該怎么,如果不想裝飾了,需要挨個去掉嗎

import timedef outer():Flag=Falsedef timmer(fun):def inner(*args,**kwargs):if Flag:start_time=time.time()ret = fun(*args,**kwargs)end_time=time.time()print("run in {} time {}".format(fun,end_time-start_time))return retelse:ret = fun(*args, **kwargs)return retreturn inner #實際上是把函數名字傳遞給timmer,timmer執行,之所以返回inner是因為inner在全局不可以被調用return timmer @outer() #之所以加執行就是把outer的返回值timmer函數的內存地址放在這里,其實就是@timmer def fun1(num):print("in func1 {}".format(num))return 1@outer() def fun2(num):print("in func2 {}".format(num))return 2@outer() def fun3(num):print("in func3 {}".format(num))return 3print(fun1(1)) print(fun2(2)) print(fun3(3))
  • 編寫裝飾器,為多個函數加上認證的功能(用戶的賬號密碼來源于文件),要求登錄成功一次,后續的函數都無需再輸入用戶名和密碼

  • 使用小知識點eval

login_status={"user":None,"status":False}def outer():Flag=Truedef auth(func):def inner(*args,**kwargs):if Flag:with open("user.txt",encoding="utf-8") as read_f:if login_status['user'] and login_status['status']:ret = func(*args, **kwargs)return retuser_info=eval(read_f.read())name=input("your name>>:").strip()password=input("your password>>:").strip()if name in user_info and user_info[name]["password"] == password:login_status["user"]=namelogin_status["status"]=Trueprint(login_status)ret = func(*args,**kwargs)return retelse:print("bad")else:ret = func(*args, **kwargs)return retreturn innerreturn auth@outer() def fun1():print("in func1")return 1@outer() def fun2():print("in func2")return 2@outer() def fun3():print("in func3")return 3fun1() fun2() fun3()
  • 多個裝飾器裝飾同一個函數

def wrapper1(func):def inner():print('wrapper1 ,before func')func()print('wrapper1 ,after func')return innerdef wrapper2(func):def inner():print('wrapper2 ,before func')func()print('wrapper2 ,after func')return inner@wrapper2 @wrapper1 def f():print('in f')f()

  結果原因如下:從后分析

?裝飾器小練習:

#編寫下載網頁內容的函數,要求功能是:用戶傳入一個url,函數返回下載頁面的結果 import time from urllib.request import urlopendef wrapper(func):def inner(*args,**kwargs):start_time=time.time()ret = func(*args,**kwargs).decode('utf-8')end_time=time.time()print("{} time is {}".format(*args,end_time-start_time))return retreturn inner@wrapper def get(url):return urlopen(url).read()# print(get('http://www.baidu.com')) get('http://www.baidu.com')

2. 迭代器

  • ?其實迭代就是我們說的,可以將某個數據集內的數據“一個挨著一個的取出來”,就叫做迭代

  • 可迭代協議的定義非常簡單,就是內部有了__iter__方法。
from collections import Iterablel = [1, 2, 3, 4] t = (1, 2, 3, 4) d = {1: 2, 3: 4} s = {1, 2, 3, 4}print(isinstance(l, Iterable)) print(isinstance(t, Iterable)) print(isinstance(d, Iterable)) print(isinstance(s, Iterable)) print(dir([1,2]))
  • 用__next__也可以遍歷,不依賴for循環

l=[1,2,3,4] l_iter=l.__iter__() #先把可迭代對象變成迭代器 print(l_iter.__next__()) #依次取值 print(l_iter.__next__()) #依次取值 print(l_iter.__next__()) #依次取值 print(l_iter.__next__()) #依次取值
  • while..try..

l=[1,2,3,4] l_iter=l.__iter__() #先把可迭代對象變成迭代器 # print(l_iter.__next__()) #依次取值 # print(l_iter.__next__()) #依次取值 # print(l_iter.__next__()) #依次取值 # print(l_iter.__next__()) #依次取值while True:try:item = l_iter.__next__()print(item)except StopIteration:break

3. 生成器

  • 一個包含yield關鍵字的函數就是一個生成器函數。yield可以為我們從函數中返回值

  • 但是yield又不同于return,return的執行意味著程序的結束,調用生成器函數不會得到返回的具體的值,而是得到一個可迭代的對象。

  • 每一次獲取這個可迭代對象的值,就能推動函數的執行,獲取新的返回值。直到函數執行結束。

  • 生成器有什么好處呢?就是不會一下子在內存中生成太多數據

def genrator_fun1():a=1yield ab=2yield bg=genrator_fun1() print(next(g)) print(next(g)) #生成器監聽文件輸入的例子

  

  

  

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

  

  

轉載于:https://www.cnblogs.com/so-cool/p/8916225.html

總結

以上是生活随笔為你收集整理的Python中的装饰器,迭代器,生成器的全部內容,希望文章能夠幫你解決所遇到的問題。

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