python day 12

 迭代器和生成器                                                                                                                    

1. 複習

(1)狀況一

 

結果:python

(2)狀況二

結果:web

 

(3)狀況三

結果:編程

 

裝飾器函數:

2.生成器

2.1 生成器函數:

def generator():
    print(1)
    return 'a'
ret = generator()
print(ret)

只要含有yield關鍵字的函數都是生成器函數,yield不能和return共用且須要寫在函數內

def generator():
    print(1)
    yield 'a'
ret = generator()
print(ret)

結果:緩存

<generator object generator at 0x0000000005766410>

注意:生成器函數 : 執行以後會獲得一個生成器做爲返回值

2.2 ret.__next__()

def generator():
    print(1)
    yield 'a'
ret = generator()
print(ret)
print(ret.__next__())

結果:

<generator object generator at 0x000000000564CA98>
1
a

執行過程:

 

(1)一個迭代

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g = generator()
ret=g.__next__()
print(ret)

執行結果:

1
a

(2)二次迭代

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g = generator()
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)

結果:

1
a
2
b

(3)三次迭代

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g = generator()
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)
ret=g.__next__()
print(ret)

 結果:

1
a
2
b
c

(4)能夠換成for循環:

def generator():
    print(1)
    yield 'a'
    print(2)
    yield 'b'
    yield 'c'
g = generator()
for i in g:
    print(i)

 結果同上:

1
a
2
b
c

(5)生成100個娃哈哈,生產一個,處理一個。

def wahaha():
    for i in range(100):
        yield '娃哈哈%s'%i
g = wahaha()
for i in g:
    print(i)

 只打印前50個:   

def wahaha():
    for i in range(100):
        yield '娃哈哈%s'%i
g = wahaha()
count = 0
for i in g:
    count += 1
    print(i)
    if count > 50:
        break

打印前50個後還能夠接着打印下一個:

def wahaha():
    for i in range(100):
        yield '娃哈哈%s'%i
g = wahaha()
count = 0
for i in g:
    count += 1
    print(i)
    if count > 50:
        break
print(g.__next__())

打印前50個後還能夠接着打印50個:

def wahaha():
    for i in range(100):
        yield '娃哈哈%s'%i
g = wahaha()
count = 0
for i in g:
    count += 1
    print(i)
    if count > 50:
        break
for i in g:
    count += 1
    print(i)
    if count > 100:
        break

 與以上區分:

l = [1,2,3,4,5] #可迭代的
#在for造成迭代器 for i in l: print(i) if i == 2: break for i in l: print(i)

執行結果(不是接着第一個執行的):app

1
2
1
2
3
4
5

 相似於:

def wahaha():
    for i in range(100):
        yield '娃哈哈%s'%i
g = wahaha()
g1 = wahaha()
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g1.__next__())

  結果:ide

娃哈哈0
娃哈哈1
娃哈哈2
娃哈哈0

監聽文件輸入的例子 

一邊在文件file,中輸入,一邊輸出查看函數

def tail(filename):
    f = open(filename,encoding='utf-8')
    while True:
        line = f.readline()
        if line.strip():
            yield line.strip()

g = tail('file')
for i in g:
    if 'python' in i:
        print('***',i)

3.裝飾器精講

4.1普通函數的方法和被裝飾函數的方法區別

普通函數:url

def wahaha():
    '''
    一個打印娃哈哈的函數
    :return:
    '''
    print('娃哈哈')

print(wahaha.__name__) #查看字符串格式的函數名
print(wahaha.__doc__)  #document

被裝飾函數:spa

 

def wrapper(func):  #func = holiday
  def inner(*args,**kwargs): print('在被裝飾的函數執行以前作的事') ret = func(*args,**kwargs) print('在被裝飾的函數執行以後作的事') return ret return inner @wrapper #holiday = wrapper(holiday) def holiday(day): '''這是一個放假通知''' print('全體放假%s天'%day) return '好開心' print(holiday.__name__) print(holiday.__doc__)

 

被裝飾函數執行結果:3d

inner
None

想正常打印被裝飾函數的方法

@wraps(func)帶參數的裝飾器
from functools import wraps
def wrapper(func):  #func = holiday
    @wraps(func)    
    def inner(*args,**kwargs):
        print('在被裝飾的函數執行以前作的事')
        ret = func(*args,**kwargs)
        print('在被裝飾的函數執行以後作的事')
        return ret
    return inner

@wrapper   #holiday = wrapper(holiday)
def holiday(day):
    '''這是一個放假通知'''
    print('全體放假%s天'%day)
    return '好開心'

print(holiday.__name__)
print(holiday.__doc__)

 執行結果:

holiday
這是一個放假通知

4.裝飾器做業

題目1:

# 1.編寫裝飾器,爲多個函數加上認證的功能(用戶的帳號密碼來源於文件),
# 要求登陸成功一次,後續的函數都無需再輸入用戶名和密碼

 執行代碼:

FLAG = False
def login(func):
    def inner(*args,**kwargs):
        global FLAG
        '''登陸程序'''
        if FLAG:
            ret = func(*args, **kwargs)  # func是被裝飾的函數
            return ret
        else:
            username = input('username : ')
            password = input('password : ')
            if username == 'boss_gold' and password == '22222':
                FLAG = True
                ret = func(*args,**kwargs)      #func是被裝飾的函數
                return ret
            else:
                print('登陸失敗')
    return inner

@login
def shoplist_add():
    print('增長一件物品')

@login
def shoplist_del():
    print('刪除一件物品')

shoplist_add()
shoplist_del()
代碼

題目2:

# 2.編寫裝飾器,爲多個函數加上記錄調用功能,要求每次調用函數都將被調用的函數名稱寫入文件

執行代碼:

def log(func):
    def inner(*args,**kwargs):
        with open('log','a',encoding='utf-8') as f:
            f.write(func.__name__+'\n')
        ret = func(*args,**kwargs)
        return ret
    return inner
@log
def shoplist_add():
    print('增長一件物品')
@log
def shoplist_del():
    print('刪除一件物品')
shoplist_add()
shoplist_del()
shoplist_del()
shoplist_del()
shoplist_del()
shoplist_del()
執行代碼

進階做業(選作):

# 1.編寫下載網頁內容的函數,要求功能是:用戶傳入一個url,函數返回下載頁面的結果

執行代碼:

from urllib.request import urlopen
def get(url):
    code = urlopen(url).read()
    return code
ret = get('http://www.baidu.com')
print(ret)

選作2:

爲題目1編寫裝飾器,實現緩存網頁內容的功能:
# 具體:實現下載的頁面存放於文件中,若是文件內有值(文件大小不爲0),就優先從文件中讀取網頁內容,不然,就去下載,而後存到文件中

執行代碼:

import os
from urllib.request import urlopen
def cache(func):
    def inner(*args,**kwargs):
        if os.path.getsize('web_cache'):
            with open('web_cache','rb') as f:
                return f.read()
        ret = func(*args,**kwargs)  #get()
        with open('web_cache','wb') as f:
            f.write(b'*********'+ret)
        return ret
    return inner

@cache
def get(url):
    code = urlopen(url).read()
    return code


# {'網址':"文件名"}
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
ret = get('http://www.baidu.com')
print(ret)
執行代碼

分紅兩部分:

5.裝飾器進階內容

 5.1帶參數的裝飾器

500個函數 

代碼:

import time
FLAGE = False
def timmer_out(flag):
    def timmer(func):
        def inner(*args,**kwargs):
            if flag:
                start = time.time()
                ret = func(*args,**kwargs)
                end = time.time()
                print(end-start)
                return ret
            else:
                ret = func(*args, **kwargs)
                return ret
        return inner
    return timmer
# timmer = timmer_out(FLAGE)
@timmer_out(FLAGE)    #wahaha = timmer(wahaha)
def wahaha():
    time.sleep(0.1)
    print('wahahahahahaha')
代碼

 5.2多個裝飾器裝飾一個函數

 推薦書籍:Python核心編程 

def wrapper1(func):
    def inner1():
        print('wrapper1 ,before func')
        ret = func()
        print('wrapper1 ,after func')
        return ret
    return inner1

def wrapper2(func):
    def inner2():
        print('wrapper2 ,before func')
        ret = func()
        print('wrapper2 ,after func')
        return ret
    return inner2

def wrapper3(func):
    def inner3():
        print('wrapper3 ,before func')
        ret = func()
        print('wrapper3 ,after func')
        return ret
    return inner3

@wrapper3
@wrapper2
@wrapper1
def f():
    print('in f')
    return '哈哈哈'

print(f())
例子

 

  

用途:即記錄用戶的登陸狀況,又計算這個函數的執行時間

 

 6.做業 

1.默寫:帶參數的裝飾器。須要標註代碼的執行步驟。
2.整理做業:函數的知識點以及裝飾器相關做業。裝飾器做業須要本身寫一遍,並給做業加註釋。
3.週末大做業:實現員工信息表
文件存儲格式以下:
id,name,age,phone,job
1,Alex,22,13651054608,IT
2,Egon,23,13304320533,Tearcher
3,nezha,25,1333235322,IT

如今須要對這個員工信息文件進行增刪改查。

不容許一次性將文件中的行都讀入內存。
基礎必作:
a.能夠進行查詢,支持三種語法:
select 列名1,列名2,… where 列名條件
支持:大於小於等於,還要支持模糊查找。
示例:
select name, age where age>22
select * where job=IT
select * where phone like 133

 

進階選作:
b.可建立新員工記錄,id要順序增長
c.可刪除指定員工記錄,直接輸入員工id便可
d.修改員工信息
語法:set 列名=「新的值」 where 條件
#先用where查找對應人的信息,再使用set來修改列名對應的值爲「新的值」

注意:要想操做員工信息表,必須先登陸,登錄認證須要用裝飾器完成
其餘需求儘可能用函數實現

做業要求:1.今天的第二、3個做業一塊兒打包交上來2.放在做業2文件夾中須要交整理的函數相關的思惟導圖整理的函數知識點的博客裝飾器做業加註釋3.大做業放在3文件夾中  文件夾中須要包括:  代碼  流程圖(請上交一張png圖片。若是沒有合適的畫圖軟件,能夠用processon畫)  readme文件(請上交一個txt文件,對做業進行一些簡單說明,包括做業的總體思路,如何運行,實現了哪些功能,遇到了哪些問題等。)

相關文章
相關標籤/搜索