4)裝飾器、迭代器、生成器以及內置函數

                裝飾器、迭代器、生成器以及內置函數python

 

 

裝飾器:程序員

原函數先後增長功能,切不改變函數的本來使用方式app

 

import time
def wrapper(f):
    def inner():
        start = time.time()
        f()
        end = time.time()
        print('執行效率爲%s'%(end-start))
    return inner

@wrapper
def func():
    print('this is func')
    time.sleep(0.3)
func()
ide

 

import time
def wrapper(f):
    def inner(*args,**kwargs):#帶參數的裝飾器
        start = time.time()
        f(*args,**kwargs)
        end = time.time()
        print('執行效率爲%s'%(end-start))
    return inner

@wrapper
def func(a,b):
    print(a,b)
    print('this is func')
    time.sleep(0.3)
func(111,222)
函數

 

 

再加一個666this

import time
def wrapper(f):
    def inner(*args,**kwargs):#帶參數的裝飾器
        start = time.time()
        set = f(*args,**kwargs)
        end = time.time()
        print('執行效率爲%s'%(end-start))
        return set
    return inner

@wrapper
def func(a,b):
    print(a,b)
    print('this is func')
    time.sleep(0.3)
    return 666
print(func(111,222))
spa

 

 

進階需求:設計

狀況一:3d

500個函數日誌

   設計裝飾器,確認是否生效

import time
FLAG = True
def outer(flag):
    def wrapper(f):
        def inner(*args,**kwargs):#帶參數的裝飾器
            if flag == True:

                start = time.time()
                set = f(*args,**kwargs)
                end = time.time()
                print('執行效率爲%s'%(end-start))
            else:
                set = f(*args,**kwargs)
            return set
        return inner
    return wrapper

@outer(FLAG)
def func(a,b):
    print(a,b)
    print('this is func')
    time.sleep(0.3)
    return 666
print(func(111,222))

 

 

狀況二:

登錄,紀錄日誌

 

 

 

login_info = {'alex':False}

def login(func):
    def inner(name):
        if login_info[name] !=True:
            user = input('>>>user')
            pwd = input('>>pwd')
            if user =='alex' and pwd =='alex3714':
                login_info[name] = True
        if login_info[name]  == True:
             ret = func(name)
             return ret
    return inner


def wrapper1(func):   #f
    def inner1():
        print('wrapper1 ,before func')
        func()   # f
        print('wrapper1 ,after func')
    return inner1

def wrapper2(func):  # inner1
    def inner2():
        print('wrapper2 ,before func')
        func()   # inner1
        print('wrapper2 ,after func')
    return inner2

@wrapper2
@wrapper1
def f():
    print('in f')

f()

 

 圖片1.png

 

import time
login_info = {'alex':False}
def login(func):
    def inner(name):
        if login_info[name] !=True:
            user = input('>>>user')
            pwd = input('>>pwd')
            if user =='alex' and pwd =='alex3714':
                login_info[name] = True
        if login_info[name]  == True:
             ret = func(name)
             return ret
    return inner

def timmer(f):
    def inner(*args,**kwargs):
        start = time.time()
        ret = f(*args,**kwargs)
        end = time.time()
        print('執行效率%s'%(end-start))
        return ret
    return inner
@login
@timmer
def index(name):
    print('歡迎%s考到博客園'%name)
    time.sleep(0.3)
@login
@timmer
def manager(name):
    print('歡迎%s考到博客園管理頁面'%name)
    time.sleep(0.3)
index('alex')
manager('alex')

 

迭代器和生成器

 

迭代器:

凡是可使用for循環取值的都是可迭代的

#從列表、字典中取值
# index索引
#for 凡是經過for循環取值的都是可迭代的

 

 

可迭代協議:

內部有__iter__方法的都是可迭代的

 

迭代器協議:

內部有__iter____next__方法的都是迭代器

建立迭代器使用__iter__() 或者 iter()

dir()能夠查看使用的內置方法

l = [1,2,3]
ll = iter(l)
print(ll.__next__())
print(ll.__next__())

 

 

l = [1,2,3]
lst_iter = iter(l)  #lst_iter = iter(l) == lst_iter = [1,2,3].__iter__()

while True:
    print(next(lst_iter))   #lst_iter.__next__()

 

 

 

l = [1,2,3]
ll = iter(l)
while True:

    print(next(ll))   #報錯了

 

 

沒有就會出錯

l = [1,2,3]
lst_iter = iter(l)  #lst_iter = iter(l) == lst_iter = [1,2,3].__iter__()

while True:
    try:
        print(next(lst_iter))   #lst_iter.__next__()
    except StopIteration:
        break

 

 

 

 

總結:

什麼是可迭代:內部有__iter__

 

什麼是迭代器:迭代器=iter(可迭代的) 自帶__next__方法

節省內存

 

Range()

 

from collections import  Iterable,Iterator
print(range(10000))
print(isinstance(range(10000),Iterable))  #True
print(isinstance(repr(10000),Iterator))   #False


 

 

Python2range會生成一個列表,將用來存儲生成全部的值

 圖片2.png

Python3range無論要多少,都不會生成實際的值

在使用的時候在生成

for i in range(1000):

 

節省內存,速度快

特性:惰性運算

 

 

生成器:

本身寫的迭代器就是生成器

兩種本身寫生成器的機制:

生成器函數:

凡是帶有yield的函數是個生成器

 

def func():
    print('****')
    yield 1
g = func()
next(g)

 

 

 

def func():
    print('****')
    yield 1
    print('^^^^')
    yield 2
g = func()
print('___',next(g))
print('===',next(g))

 

 

 

Yield 記錄當前所在位置,等待下一次next來觸發函數的狀態

想要執行要next

def cloth_g(name):
    for i in range(name):
        yield 'choth_g%s'%i
g = cloth_g(10)
next(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

 

 

 

 

使用生成器監聽文件輸入:

import time
def lister_file():
    with open('userinfo') as f1:
        while True:
            line = f1.readline()
            if line.strip():
                yield line.strip()
            time.sleep(0.3)

g = lister_file()
for i in g:
    print(i)
    if i =='error':
        break

 

 

 

 

 圖片3.png

 

Send 關鍵字

在執行next的時候,傳遞一個參數給生成器函數的內部

1)

def func():
    print(1111)
    yield 1
    print(2222)
    yield 2
    print(3333)
    yield 3

func()
next(func())
next(func())

 

 

 

 

2) :

def func():
    print(1111)
    yield 1
    print(2222)
    yield 2
    print(3333)
    yield 3

g = func()
ret = next(g)
print(ret)

 

 圖片4.png

3) :

 

def func():
    print(1111)
    ret1 = yield 1
    print(2222,'ret1:',ret1)
    ret2 = yield 2
    print(3333,'ret2:',ret2)
    yield 3

g = func()
ret = next(g)
print(g.send('alex'))
print(g.send('lxf'))

 

 

 

向生成器中傳遞值,有個激活過程,第一次必須用next觸發這個生成器

def average():
    sum_money = 0  #總錢數
    day = 0   #天數
    avg = 0   #平均的錢
    while True:
        money = yield avg
        sum_money += money
        day +=1
        avg =  sum_money/day
g = average()
next(g)
print(g.send(200))
print(g.send(300))

 圖片5.png

 

 

例子:

 

 

 

預激生成器:

就是吧要激活的next放到一個裝飾器當中,好比說有多個程序須要激活的話,能夠這樣作,爲了簡便,若是要是就一個程序的話就沒有必要了

 

yield from

 

 

 

def generator_func():
    for i in range(5):
        yield i
    for j in 'hello':
        yield j
g = generator_func()

#如何取值

#1,next、隨時能夠中止,最後會報錯
print(next(g))
print(next(g))

#2,for循環、從頭至尾遍歷一次,不遇到break、return不中止
for i in g:
    print(i)


#3,list、tuple
print(list(g))#一次性全部的都轉換了,若是多太佔內存
print(g)

 

上面的內容能夠進行替換成以下:

def generator_func():
    yield from range(5)
    yield from 'hello'
    # for i in range(5):
    #     yield i
    # for j in 'hello':
    #     yield j
g = generator_func()
for i in g:
    print(i)

 

總結:

 

1)生辰器函數,是咱們python程序員實現迭代器的一種手段

2)主要特徵是在函數中含有yield

3)調用一個生成器函數,不會執行這個函數中的代碼,只是會得到一個生成器代碼

4)只有從生辰器中取值的時候,纔會執行函數內部的代碼,且每獲取一個數據才執行的到這個數據的代碼

5)獲取數據方式,nextsend 循環 數據類型的強制轉化

6)Yield 返回值的簡便方法,若是自己就是循環一個可迭代,且要把可迭代數據中的每個元素都返回,能夠用yield from

7)使用send的時候,在生成器創造出來以後須要進行預激活,這一步可使用裝飾器完成

8)生成器特色:節省內存、惰性運算

9)生成器用來解決內存和程序功能之間的解耦

 

 


 

 

 

 

列表推到試:表現爲   []

new = []
for i in range(10):
    new.append(i**2)
print(new)

 


#上面的複雜很差
print([i **2 for i in range(10)])#列表推到式

 

 

ll = [1,2,3,-5,6,20,-7]#求每一個數的餘數
print([ i%2 for i in ll])

 

 

ll = [1,2,3,-5,6,20,-7]
print([i for i in ll if i %2 ==0])

 

#30之內搜友能被3整除的數
print([i for i in range(30) if i % 3 ==0])
#30之內搜友能被3整除的數的平方
print([i**2 for i in range(30) if i % 3 ==0])

#:找到嵌套列表中名字含有兩個‘e’的全部名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
         ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
# for i in names:
#     for j in i:     #複雜很差
#         if j.count('e') ==2:
#             print(j)

print( [j for i in names for j in i if j.count('e') ==2])

 

 

生成器表達式:表現爲 ()

 

 圖片6.png

 

 

練習題:

 

 圖片7.png

 

自定義函數:

本身定義的【name = uuu’】

 

 

內置函數:

拿過來直接用的,python直接封裝好的

Printlenmaxmindir

 

迭代器/生成器相關的:

Rangenext iter

 

做用域相關的:

Globals

Locals

 

其餘:

Input

Print:九九乘法表
for i in range(1,10):
    for j in range(1,i+1):
        print('%s*%s=%2s'%(i,j,i*j),end=' ')
    print()

 

print(1,2,3,4,5,sep=';',end=' ')#1;2;3;4;5
print(1,2,3,4,5,sep=';',end='')#1;2;3;4;5

 

 

進度條

import time
for i in range(0,101,2):
    time.sleep(0.1)
    char_num = i//2
    per_str = '\r%s%% : %s\n' % (i, '*' * char_num) if i ==100 else'\r%s%% : %s'%(i,'*'*char_num)
    print(per_str,end='')

 

 

import time
for i in range(0,101,2):
    time.sleep(0.1)
    char_num = i//2
    if i ==100:
        per_str = '\r%s%% : %s\n' %(i,'*'* char_num)
    else:
        per_str='\r%s%%: %s'%(i,'*' *char_num)
    print(per_str,end='')

 

 

 

Hash

對可hash的數據類型進行hash以後會的到一個數字
在一次程序的執行過程當中,對相同的可哈希變量,哈希以後的結果永遠相同
在一次程序的執行過程當中,對不相同的可哈希變量,哈希以後的結果幾乎是不相同的
hash字典底層的存儲和set 集合的去重機制都有關

 

Id():

Open

Import

Help

Callable:可調用

def func():
    pass
a = 1
print(callable(func))#True
print(callable(a))#False

 

 

Dir: 查看這一個變量的全部方法、屬性

Bin:進制


print(bin(10))#二進制
print(oct(10))#十進制
print(hex(10))#十六進制


abs計算數字絕對值

print(abs(4))
print(abs(-4))

 

 

divmod:商餘函數

print(divmod(10,2))#(5, 0)
print(divmod(7,3))#(2, 1)
print(divmod(9,7))#(1, 2)

 

 

Round:小數精確

print(round(3.1415926,4))#3.1416  小數精確四捨五入

 

 

Pow:平方

print(pow(2,3))#8
print(pow(3,2))#9

 

 

Sum:求和

print(sum([1,2,3,4,5]))

 

 

Min:計算最小值

print(min([1,2,3,4,5]))#1
print(min([1,2,3,4,5]))#1
print(min(1,-2,3,-4,key=abs))#1

 

 


def func(num):
    return num%2
print(min(-2,3,-4,key=func))

 

Max:和min同樣

 

List

Tuper

Reverse:反轉

Reversed()
ret = [1,2,3,4,5]
ret1 = reversed(ret)
ret2 = reversed((1,2,3,4,5))
print(ret)#[1, 2, 3, 4, 5]
print(list(ret1))#[5, 4, 3, 2, 1]
print(list(ret2))#[5, 4, 3, 2, 1]

 

 

Str

Format

Bytes

Ord

 

 

print(ord('a'))#小寫的a-z   97+26   大寫的A-Z 65+26

 

Chr

print(chr(97))#a


Repr:
print(repr(1))#1
print(repr('1'))#'1'

 

 

 

Enumerate:枚舉函數

 

l = ['蘋果','香蕉','橘子']
for index,i in enumerate(l,1):
    print(index,i)

 

l = ['蘋果','香蕉','橘子']
ret = enumerate(l,1)
for i in ret:
    print(i[0],i[1])

 

 

 

 

沒啥用:

 圖片8.png

 

Zip:拉鍊方法:

ss =zip([1,2,3,4],('a','b','c','d'))
for i in ss:
    print(i)

 

 

 

 

Filter用於過濾不須要的元素


ll = [1,4,6,7,12,17]
def func(num):
    if num %2 ==0:return True
for i in filter(func,ll):
    print(i)

g=(i for i in ll if i%2 ==0)

 

 


l = ['test',None,'','str', ' ','END']
def func(item):
    if item and item.strip():return True
for i in filter(func,l):
    print(i)

 

 

 

Map

def func(num):
    return num**2
for i in map(func,range(10)):print(i)

 

 

Sorted:排序功能

 


l = [1,-4,-2,3,-5,6,5]
l.sort(key=abs)
print(l)

 

 


l = [1,-4,-2,3,-5,6,5]
new = sorted(l,reverse=True)
print(new)


 

 

 

l = [[1,2,],[3,4,5,6],(7,),'123']
print(sorted(l,key=len))

 

 

eval

eval('print(123)')

 

 

exec

exec ('print(123)')#123
eval('print(123)')#123

print(eval('1+2-3*20/(2+3)')) -9.0
print(exec('1+2-3*20/(2+3)'))# none

 

 

 

匿名函數:

Lambda表達式:

邏輯比較簡單
1):

add = lambda a,b: a+b
print(add(1,2))



2):

def func(num):
    return num**2
for i in map(func,range(10)):print(i)



for i in map(lambda num : num**2,range(10)):print(i)

 

 

 

 

3):
def func(num):
    return num%2
print(max(-2,3,-4,key=func))


print(max(-2,3,-4,key=lambda num:num%2))

 

 

 

 

 

遞歸:

 

 圖片9.png

 

 

 圖片10.png

 

  圖片11.png

 

遞歸本身調用本身

須要有一箇中止的條件

圖片12.png 

二分法:

l = [1,2,3,4,5,6,7,8,9,10,11]
def binary_search(l,num):
     print(l)
     if len(l) == 0:
         print('not has num')
         return
     mid_index = len(l)//2
     if num > l[mid_index]:
         binary_search(l[mid_index+1:],num)
     elif num < l[mid_index]:
         binary_search(l[0:mid_index],num)
     else:
         print('find it')
binary_search(l,9)

相關文章
相關標籤/搜索