一: 装饰器
1:装饰器模板
def wrapper(func):
def inner(*args,**kwargs):
ret =func(*args,**kwargs)
return ret
return inner
开放封闭原则
对扩展是开放的
对修改时封闭的
import time
def wrapper(func):
def innner(*args,**kwargs):
start = time.time()
time.sleep(1)
func(*args,**kwargs)
end = time.time()
print(end-start)
return innner
@wrapper # func = wrapper(func)
def func():
print('hello world')
func()
# 给函数加上认证功能,登录一次就可以多次调用函数
FLAG = False
def login(func):
def innner(*args,**kwargs):
global FLAG
if FLAG:
ret =func(*args,**kwargs)
return func
else:
username = input('username: ')
password = input('password: ')
if username == 'wangys' and password == 'wangys':
FLAG = True
ret =func(*args,**kwargs)
return func
else:print("用户名密码错误")
return innner
@login
def shoplist_add():
print('增加一个商品')
@login
def shoplist_delete():
print('删除一个商品')
shoplist_add()
shoplist_delete()
带参数的装饰器
多个装饰器装饰一个函数
二:迭代器
所谓迭代就是可以将数据集种的数据一个一个的取出来
比如说for循环,可以将list tuple dic str set range f enumerate 种的数据集一个一个的取出来
列表 l = [1,2,3,4] for i in l: print(i) 元祖 t = (1,2,3,4 for i in t: print(i) 字典 dic = {'name':'wangys','age':18} for i in dic: print(i) 字符串 name = 'wangys' for i in name: print(i)
可迭代协议:只要含有__iter__方法的都是可迭代的,也就是可以被for循环
# dir方法可以将所有方法取到,我们可以通过下面的手段来查看是否有__iter__方法,也就是是否可以被for循环
print('__iter__' in dir([])) print('__iter__' in dir('')) print('__iter__' in dir(())) print('__iter__' in dir({}))
迭代器
有__iter__和__next__方法
# 列表通过__iter__方法,得到了一个迭代器对象
print([].__iter__()) <list_iterator object at 0x000001CF7C9AD0B8>
# 查看迭代器相对于可迭代对象增加了哪些方法 print(dir([])) print(dir([].__iter__())) print(set(dir([].__iter__()))-set(dir([])))
{'__length_hint__', '__setstate__', '__next__'}
__next__方法就可以将一个一个元素取出
# list是可迭代对象 # list_iterator,是通过list的__iter__方法获得的迭代器 # 通过迭代器的__next__方法,一个一个取出值 list = [1,2,3] list_iterator = list.__iter__() print(list_iterator.__next__()) print(list_iterator.__next__()) print(list_iterator.__next__()) print(list_iterator.__next__()) # 因为有三个元素,所以这里会报错StopIteration
# 我们可以通过while循环取出数据
# 会报错 list = [1,2,3,4] list_iterator=list.__iter__() while True: item = list_iterator.__next__() print(item) StopIteration # 通过异常处理机制 list = [1,2,3,4] list_iterator=list.__iter__() while True: try: item = list_iterator.__next__() print(item) except StopIteration: break
for循环就是基于迭代器协议提供了一个统一的可以遍历所有对象的方法,即在遍历之前,先调用对象的__iter__方法将其转换成一个迭代器,然后使用迭代器协议去实现循环访问
迭代器的好处:
节省内存空间 range f
三:生成器
生成器本身是一种迭代器
方法:
1: 通过生成器函数
2: 生成器表达式
3.1 生成器函数:函数内部含有yield的函数就是生成器函数
yield和return的区别
yield不会终止函数,return会
yield不能与return共用,yield只能在函数内部,
def generator(): # 生成器函数 print(1) yield 'a' ret = generator() # ret是一个生成器 print(ret)
<generator object generator at 0x0000018492149830>
# 函数执行后,会得到一个生成器函数,该生成器既有__iter__和__next__方法
def generator(): # 定义一个生成器函数 print(1) yield 'a' print(2) yield 'a' g = generator() # 得到一个生成器g ret = g.__next__() print(ret) ret = g.__next__() print(ret) ret = g.__next__() print(ret)
def generator(): print(1) yield 'a' print(2) yield 'a' g = generator() for i in g: print(i)
从生成器取数据,__next__ ,for
# 使用send获取生成器数据
def generator(): # 定义一个生成器函数 print('123') content = yield '**a' print('456') print(content) yield '**b' g = generator() # 得到一个生成器 ret =g.__next__() # 执行generator,到yield,并把返回值给ret print(ret) # 打印返回值 ret =g.send('haha') # 执行generator,并把'haha'赋值给content,并且执行到yield,返回值给ret print(ret) # 打印ret
3.2 生成器表达式
- 跟列表推导式相比,它很省内存,得到的是一个生成器
# 100内被3整除得数
g1 = (i for i in range(100) if i%3 ==0) print(g1) print(list(g1))
# 100内能被3整除得数得平方
g1 = (i**2 for i in range(100) if i%3==0) print(list(g1))
# 名字带两个e
names = [ ['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva'] ] # 常规做法 l1=[] for line in names: for name in line: if name.count('e') ==2: l1.append(name) print(l1) # 列表推导式 l1=[name for line in names for name in line if name.count('e') ==2] print(l1) # 生成器表达式 g1 = (name for line in names for name in line if name.count('e')==2) print(list(g1)
四: 各种推导式
- 没有元祖推导式
4.1 列表推导式
语法: [结果 for循环 条件判断]
# 取1-100内的偶数
# 常规做法 l1=[] for num in range(100): if num%2 ==0: l1.append(num) print(l1) # 列表推导式 li = [num for num in range(100) if num%2 ==0] print(li)
# 将列表中元素长度大于3的元素大写
name = ['wangys','wc','huisz','cyf'] l1=[ i.upper() for i in name if len(i) >3] print(l1)
# [(0, 1), (0, 3), (2, 1), (2, 3), (4, 1), (4, 3)]
l1 = [(i,j) for i in range(5) for j in range(5) if i%2==0 and j%2==1] print(l1)
# M = [[1,2,3],[4,5,6],[7,8,9]] 取出[3,6,9]
M = [[1,2,3],[4,5,6],[7,8,9]] l1 = [ i[2] for i in M] print(l1)
# [3,6,9] ----> [[1,2,3],[4,5,6],[7,8,9]]
m = [3, 6, 9] l1 = [[i-2,i-1,i] for i in m] print(l1)
# 求出50以内能被3整除的数的平方,并放入到一个列表中
l1 = [i**2 for i in range(50) if i%3 ==0] print(l1)
#
x = { 'name':'wangys', 'Values':[{'timestamp':1517991992.94, 'values':100,}, {'timestamp': 1517992000.94, 'values': 200,}, {'timestamp': 1517992014.94, 'values': 300,}, {'timestamp': 1517992744.94, 'values': 350}, {'timestamp': 1517992800.94, 'values': 280} ],} l1 = [ (el['timestamp'],el['values']) for el in x['Values']] print(l1)
# [(1517991992.94, 100), (1517992000.94, 200), (1517992014.94, 300), (1517992744.94, 350), (1517992800.94, 280)]
4.2 字典推导式
一句话生成字典
# 根据两个列表生成一个字典
lst1 = ['jay', 'jj', 'sylar'] lst2 = ['周杰伦', '林林俊杰', '邱彦涛'] dic = {lst1[k]:lst2[v] for k in range(len(lst1)) for v in range(len(lst2))} print(dic)