def f1(b):
def f2():
print(b) # 這樣也是閉包
defwrapper(func):
definner(*args,**kwargs):
"""被裝飾函數執行之前要添加的代碼"""
ret = func(*args,**kwargs)
"""被裝飾函數執行之後要添加的代碼"""
return ret
return inner
deftimmer(qqx):#timmer是裝飾器的名字,傳入的參數就是被裝飾的函數
definner():#在裝飾器中需要定義一個內部函數
print('調用func之前')
qqx() #被裝飾的函數,並且要執行
print('調用func之後')
returninner#將內部函數的名字返回
@timmer#語法糖 func = timmer(func)
deffunc():
print('公司好老闆好同事好')
func()
deftimmer(qqxing):#timmer是裝飾器的名字,傳入的參數就是被裝飾的函數
definner(*args,**kwargs):#在裝飾器中需要定義一個內部函數
print('調用func之前')
ret = qqxing(*args,**kwargs)#被裝飾的函數,並且要執行
print('調用func之後')
return ret
return inner#將內部函數的名字返回
@timmer#語法糖 func = timmer(func)
deffunc(name):
print('%s的公司好老闆好同事好'%(name))
return 1111111111
ret = func('哈哈')
print('result : %s'%ret)
flag = False
deflogin(func):
definner(*args,**kwargs):
globalflag
ifflag ==False:
username = input('用戶名:')
password = input('密碼:')
if username =='alex'and password =='somebody':
print('登錄成功')
flag = True
if flag ==True:
ret = func(*args,**kwargs)
return ret
return inner
@login
defart():
print('歡迎來到文章頁')
@login
defdar():
print('歡迎來到日記頁')
art()
dar()
deflog(func):
definner(*args,**kwargs):
f =open('geci','a',encoding='utf-8')
f.write('你要調用%s函數了\n'%func.__name__)
f.close()
ret = func(*args,**kwargs)
return ret
return inner
@log
deff1():
print('f1')
@log
deff2():
print('f2')
f1()
f2() ### 成功將'你要調用f1函數了你要調用f2函數了'寫入’geci'文件
①
print(dir(l)) # 打印關於l的方法
print(dir(lst_iter))
print(set(dir(lst_iter)) - set(dir(l))) # 兩個用法的差集
list_iter.__next__() # 迭代器比可迭代的多一個__next__方法
②
l = ['ha','hei','hou']
ret = l.__iter__()
print(ret.__next__()) # ha
print(ret.__next__()) # hei
print(ret.__next__()) # hou
①
print('__iter__' in dir([1,2,3,4])) # True
print('__next__' in dir([1,2,3,4])) # False
②
from collections import Iterable # 可迭代
from collections import Iterator # 迭代器
print(isinstance([1,2,3,4],Iterable)) # True
str_iter = 'abc'.__iter__()
print(isinstance(str_iter,Iterator)) # True
print(isinstance('abc',Iterator)) # False
l = [1,2,3,4,5]
l_iter = l.__iter__()
while True:
try:
print(l_ter.__next__())
except StopIteration:
break
def g_func():
print('I am here.')
yield 1
print('I am OK!')
yield 2
g = g_func() # 若只到這一步,什麼都不打印
print(g.__next__()) # 若沒有 print ,只有g.__next__則只打印’ I am here.‘
### 結果:I am here. \n 1
print(g.__next__()) # 都打
def cloth():
for i in range(1,1000001):
yield '衣服%s'%i
g = cloth
for i in range(50): # 取出50件
print(g.__next__())
def func():
print('*********')
a = yield 5
yield 10
g = func
num = g.__next__()
print(num)
num2 = g.send('jieshenziai')
print(num2)
def tail():
f = open('文件',encoding='utf-8')
f.seek(0,2) (光標移動到最後)
while True:
line = f.readline()
if line:
yield line
import time
time.sleep(0,1)
g = tail()
for i in g:
print(i.strip())
num2 = g.send('惹人感慨')
③下面是一個比較6的 計算移動平均值。def average():
total = 0.0
count = 0
average = None
while True:
term = yield average
total += term
count += 1
average = total / count
g_avg = average()
g_avg.__next__()
print(g_avg.send(10))
print(g_avg.send(30))
print(g_avg.send(50))
五、生成器的預激裝飾器def init(func):
def inner(*args,**kwargs):
ret = func(*args,**kwargs)
ret.__next__()
return ret
return inner
因爲,send之前總是要 next 所以,就有了這個預激裝飾器六、小栗子輸出 A,B,C,D
①方法
def func():
a = 'AB'
b = 'CD'
for i in a:
yield i
for i in b:
yield i
func()
g = func()
for i in g:
print(i)
②方法
def func():
a = 'AB'
b = 'CD'
yield from a # 這是py3 中特有的
yield from b
func()
g = func()
for i in g:
print(i)
七、觸發執行的方式:next(send):執行幾次那幾個數據,取完會報錯
for循環:每次取一個,取完爲止,不會報錯
八、生成器表達式
列表推導式:
y = range(30)
x = [i*i for i in y ]
生成器表達式:(這個比較好,因爲它每次就取一個)
g = (i*i for i in y )
for i in g:
print(i)
小栗子:(雞蛋和雞的關係)
l = ['雞蛋%s'%i for i in range(10)]
print(l)
laomuji = ('雞蛋%s'%i for i in range(10))
for egg in laomuji:
print(egg)
小結:惰性運算:不取值就不計算,且每一個值只能被取一次,取完爲止
可迭代對象:
擁有__iter__方法
特點:惰性運算
例如:range(),str,list,tuple,dict,set
迭代器:
擁有__iter__和__next__方法
例:iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),
reversed(list_o),map(func,list_o),filter(func,list_o),file_o
生成器Generator:
本質:迭代器,所以擁有__iter__和__next__方法
特點:惰性運算,開發者自定義
使用生成器的優點:
1、延遲計算,一次返回一個結果。不會一次生成所有結果,對大數據量處理,非常有用。
2、提高代碼可讀性