python裝飾器、迭代器、生成器

1、裝飾器

定義:本質是函數,(裝飾其他函數)就是爲其他函數添加附加功能
原則:1、不能修改被裝飾函數的源代碼
     2、被裝飾函數的調用方式不能被修改
實現裝飾器知識儲備:
	 1、函數即"變量"
	 2、高階函數:
		a:把一個函數名當做實參傳給另一個函數(不修改被修飾函數源代碼的情況下,添加新功能)
		b:返回值中包含函數名(不修改函數的調用方式,添加新功能)
	 3、嵌套函數
高階函數+嵌套函數 --> 裝飾器    
1.1、完整的裝飾器:
import time
def timmer(func):												#裝飾器
    def warpper(*args,**kwargs):
        start_time=time.time()
        func()
        stop_time=time.time()
        print('the func run time is %s' %(stop_time-start_time))
    return warpper

@timmer
def test1():
    time.sleep(3)
    print("in the test1")

test1()
--->
in the test1
the func run time is 3.000171661376953
1.2、只做到了不修改源代碼:
import time
def test(func):
    start_time=time.time()
    func()                                                 #將bar賦值給func,func()=bar()
    stop_time=time.time(
    print("the func run time is %s"%(stop_time-start_time))

def bar():                                                 #將bar這個函數傳到test函數中再運行
   print("in the bar")
   time.sleep(2)

test(bar)												   #改變了調用方式
1.3、不修改調用方式:
import time
def bar():                                                 #將bar這個函數傳到test函數中再運行
    time.sleep(2)
    print("in the bar")

def test2(func):
    print(func)
    return func

bar=test2(bar)
bar()														#調用方式沒改變
1.4、嵌套函數
在一個函數內部,在用def聲明一個新的函數
def foo():
    print("in the foo")
    def bar():
        print("in the bar")

    bar()
foo()
裝飾器—高潮版:
import time
def timmer(func):                               				#timmer(test1),func=test1
    def deco():
        start_time=time.time()
        func()                                  				#test1在這裏運行了
        stop_time=time.time()
        print("the func run time is %s"%(stop_time-start_time))
    return deco                                 				#返回deco的內存地址
@timmer                                         				#test1=timmer(test1)
def test1():
    time.sleep(3)
    print("in the test1")
test1()                                         				#test1執行實際在執行deco

--->
in the test1
the func run time is 3.000171661376953
裝飾器—又一次高潮:
import time
def timmer(func):            		                   			#timmer(test1),func=test1
    def deco(*args,**kwargs):									#加上*args,**kwargs,適配所有
        start_time=time.time()		
        func(*args,**kwargs)                    				#test1在這裏運行了
        stop_time=time.time()
        print("the func run time is %s"%(stop_time-start_time))
    return deco                                 				#返回deco的內存地址
@timmer                                         				#test1=timmer(test1)
def test1():
    time.sleep(1)
    print("in the test1")
@timmer                                         				#test1=timmer(test1)
def test2(name,age):
    print("in the test2: %s %s"%(name,age))
test1()                                         				#test1執行實際在執行deco
test2('lishang',22)

--->
in the test1
the func run time is 1.0000572204589844
in the test2: lishang 22
the func run time is 0.0
補充前戲:
user,passwd = 'lishang','22'
def auth(func):
    def wrapper(*args,**kwargs):
        username = input("Username:").strip()
        password = input("Password:").strip()
        if user == username and passwd == password:
            print('\033[32;1mUser has passwd authentication\033[0m')
            res = func(*args,**kwargs)
            return res													#加一個return
        else:
            exit('\033[31;1mInvalid username or password\033[0m')
    return wrapper

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

@auth
def home():
    print("welcome to this home page")
    return "from home"
@auth
def bbs():
    print("welcome to this bbs page")

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

--->
welcome to this index page
Username:lishang
Password:22
User has passwd authentication
welcome to this home page
from home													#可以返回值了
Username:lishang
Password:22
User has passwd authentication
welcome to this bbs page
終極高潮版:
user,passwd = 'lishang','22'
def auth(auth_type):
    print("auth func :%s"%auth_type)
    def outer_wrapper(func):
        def wrapper(*args, **kwargs):
            print("wrapper funcar :args",*args, **kwargs)
            if auth_type == "local":
                username = input("Username:").strip()
                password = input("Password:").strip()
                if user == username and passwd == password:
                    print('\033[32;1mUser has passwd authentication\033[0m')
                    res = func(*args, **kwargs)
                    return res
                else:
                    exit('\033[31;1mInvalid username or password\033[0m')
            else:
                print("不會--------------")
        return wrapper
    return outer_wrapper

def index():
    print("welcome to this index page")
@auth(auth_type="local")
def home():                                                         #home=wrapper
    print("welcome to this home page")
    return "from home"
@auth(auth_type="ldap")
def bbs():
    print("welcome to this bbs page")

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

2、迭代器

3、生成器

3.1、列表生成式
a = [ i**2 for i in range(10) ]							#列表生成式
print(a)

c = []													#上面的一行需要下面的3行生成,麻煩
for i in range(10):
    c.append(i**2)
print(c)
--->
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
3.2、生成器
生成器只有在調用時纔會生成相應的數據
#b直接在內存裏生成一個包含1億個元素的列表		#不是生成器
b = [i*2 for i in range(10000000)]
b[1000] = 2000							#能直接取到

#d是列表生成器,只有當訪問它的時候纔會生成		
d = (i*2 for i in range(10000000))		#這個列表根本沒有生成,只是保留可一個算法,需要時才生成
d[1000]									#TypeError: 'generator' object is not subscriptable
e=d.__next__()							#用__next__()取下一次數據,沒有別的方法
f=d.__next__()							#沒法取代前一次,它只記一次數據,取完就沒了
print(e)
print(f)
--->
0
2
3.3、通過函數做一個斐波那契函數的生成器
def fib(max):               #max=10
    n, a, b = 0, 0, 1
    while n < max:
        #print(b)
        yield b
        a, b = b, a+b
        n=n+1

f=fib(10)
print(f.__next__())
print(f.__next__())
print(f.__next__())
print(f.__next__())
print("start=================")
for i in f:
    print(i)

--->
1
1
2
3
start=================
5
8
13
21
34
55
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章