Python學習筆記之裝飾器

目錄


裝飾器

不改變函數代碼給函數加上新功能,並且調用方式無需改變

推導過程

在不改變方法源代碼和調用方式的情況下給方法加上功能,代碼如下:

def timer(func):
    def decorator(*args,**kwargs):
        start_time=time.time()
        func(*args,**kwargs)
        end_time=time.time()
        print('spend time : %s' %(end_time-start_time))
    return decorator


def func1():
    time.sleep(1)
    print('in the func1')


func1=timer(func1)
func1()

簡單裝飾器例子:

給函數加上運行時間計時功能,並且函數有形參

def timer(func):
    def decorator(*args,**kwargs):      #內嵌函數,也就是裝飾器,參數個數無限制
        start_time=time.time()
        func(*args,**kwargs)
        end_time=time.time()
        print('spend time : %s' %(end_time-start_time))
    return decorator                    #把裝飾器內存地址返回

@timer                          #把內存地址複製給func1,也就是函數本身,所以執行的代碼塊是剛剛定義的裝飾器,原理和上面推導過程一樣
def func1(name,age):            #有參數的函數
    time.sleep(1)
    print('in the func1,name is {_name} and age is {_age}'.format(_name=name,_age=age))


@timer
def func2():                    #無參數的函數
    time.sleep(1)
    print('in the func2')


func1("domain",18)            #再調用時就是執行裝飾器的代碼
func2()

複雜裝飾器例子:

裝飾器傳入參數,並且被裝飾函數有返回值

user,password='domain','123'

def auth(type):                         
    print("type",type)
    def out(func):
        def decor(*args,**kwargs):
            if type=="1":
                username=input('please input your name')
                userpassword=input('please input your password')
                if user==username and password==userpassword:
                    print('passed auth')
                    res=func()
                    return res
                else:
                    print('you username or password invaild.')
            elif type=="2":
                print("type ==2 ")
                username = input('please input your name')
                userpassword = input('please input your password')
                if user == username and password == userpassword:
                    print('passed auth')
                    res = func()
                    return res
                else:
                    print('you username or password invaild.')
        return decor
    return out


def index():
    print("welcome to index")

@auth("1")
def home():
    print("welcome to home")
    return "result form home "

@auth("2")
def bbs():
    print("welcome to bbs")

index()
print(home())
bbs()

生成器

一邊循環一邊生成,通過算法推斷出元素數據,成爲生成器(generator)


特點

  1. 只有在調用是時候纔會生成對應的數據
  2. 只記錄當前位置
  3. 只有一個next方法

簡單生成器-列表生成式

把列表改成生成器

c=(i*2 for i  in range(10))
print(c)                        //爲生成器 地址:<generator object <genexpr> at 0x000000BAAC687990>
print(c.__next__())             //爲生成器裏面的第一個值

複雜生成器-函數

#斐波那契
def fib(max):
    n,a,b=0,0,1
    while n<max:
        # print(b)
        yield b                 #定義b爲 生成器的值 一碰到yield函數退出
        a,b=b,a+b
        n=n+1
    return 'done'                  #生成器異常返回值

c=fib(10)
print(c.__next__())

while True:
    try:
        print(c.__next__())
    except StopIteration as e:          #捕獲超出生成器大小異常
        print("exception:",e.value)
        break

send 方法發送數據給生成器

def consumer (name):
    print("%s準備吃包子啦!"%name)
    while True:
        baozi=yield
        print("包子[%s]來了,被[%s]吃了!"%(baozi,name))

c=consumer("domain")
c.__next__()            #第一次執行 碰到yield 結束
c.send("韭菜餡")        #發送數據給生成器第二次執行 輸出語句,然後進入循環 碰到yield 結束

迭代器

  • 迭代對象:可以用於for循環的對象成爲迭代對象(Iteralbe),如:list,tuple,dict,set,str和生成器等。
  • 迭代器:可以被next函數調用並不斷返回下一個值的對象成爲迭代器(Iterator)

基本函數

  • 是否是迭代對象(導入模塊後用isinstance函數判讀):
from collections import  Iterable,Iterator
print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({"name","domain"},Iterable))
print(isinstance("domain",Iterable))
print(isinstance(123,Iterable))
  • 是否是迭代器(導入模塊後用isinstance函數判讀):
from collections import  Iterable,Iterator
print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({"name","domain"},Iterator))
print(isinstance("domain",Iterator))
print(isinstance(123,Iterator))
  • 非迭代器(可迭代對象)變成迭代器,用iter函數:
a=[1,2,3]
b=iter(a)   
b.__next__()

擴展

  • for 循環也是通過迭代器實現:
for x in range(10):
    print(x)


        break

等價於:

it = iter([0,1,2,3,4,5,6,7,8,9])
while True:
    try:
        x=it.__next__()
        print(x)
    except:
        break
  • 文件的讀取也是通過迭代器實現:
for f in f:
    print(f)

更多最新Python教程資源關注微信公衆號 凱撒網絡研究院,回覆 Python獲取。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章