目录
装饰器
不改变函数代码给函数加上新功能,并且调用方式无需改变
推导过程
在不改变方法源代码和调用方式的情况下给方法加上功能,代码如下:
def timer(func):
def decorator(*args,**kwargs):
start_time=time.time()
func(*args,**kwargs)
end_time=time.time()
print('spend time : %s' %(end_time-start_time))
return decorator
def func1():
time.sleep(1)
print('in the func1')
func1=timer(func1)
func1()
简单装饰器例子:
给函数加上运行时间计时功能,并且函数有形参
def timer(func):
def decorator(*args,**kwargs): #内嵌函数,也就是装饰器,参数个数无限制
start_time=time.time()
func(*args,**kwargs)
end_time=time.time()
print('spend time : %s' %(end_time-start_time))
return decorator #把装饰器内存地址返回
@timer #把内存地址复制给func1,也就是函数本身,所以执行的代码块是刚刚定义的装饰器,原理和上面推导过程一样
def func1(name,age): #有参数的函数
time.sleep(1)
print('in the func1,name is {_name} and age is {_age}'.format(_name=name,_age=age))
@timer
def func2(): #无参数的函数
time.sleep(1)
print('in the func2')
func1("domain",18) #再调用时就是执行装饰器的代码
func2()
复杂装饰器例子:
装饰器传入参数,并且被装饰函数有返回值
user,password='domain','123'
def auth(type):
print("type",type)
def out(func):
def decor(*args,**kwargs):
if type=="1":
username=input('please input your name')
userpassword=input('please input your password')
if user==username and password==userpassword:
print('passed auth')
res=func()
return res
else:
print('you username or password invaild.')
elif type=="2":
print("type ==2 ")
username = input('please input your name')
userpassword = input('please input your password')
if user == username and password == userpassword:
print('passed auth')
res = func()
return res
else:
print('you username or password invaild.')
return decor
return out
def index():
print("welcome to index")
@auth("1")
def home():
print("welcome to home")
return "result form home "
@auth("2")
def bbs():
print("welcome to bbs")
index()
print(home())
bbs()
生成器
一边循环一边生成,通过算法推断出元素数据,成为生成器(generator)
特点
- 只有在调用是时候才会生成对应的数据
- 只记录当前位置
- 只有一个next方法
简单生成器-列表生成式
把列表改成生成器
c=(i*2 for i in range(10))
print(c) //为生成器 地址:<generator object <genexpr> at 0x000000BAAC687990>
print(c.__next__()) //为生成器里面的第一个值
复杂生成器-函数
#斐波那契
def fib(max):
n,a,b=0,0,1
while n<max:
# print(b)
yield b #定义b为 生成器的值 一碰到yield函数退出
a,b=b,a+b
n=n+1
return 'done' #生成器异常返回值
c=fib(10)
print(c.__next__())
while True:
try:
print(c.__next__())
except StopIteration as e: #捕获超出生成器大小异常
print("exception:",e.value)
break
send 方法发送数据给生成器
def consumer (name):
print("%s准备吃包子啦!"%name)
while True:
baozi=yield
print("包子[%s]来了,被[%s]吃了!"%(baozi,name))
c=consumer("domain")
c.__next__() #第一次执行 碰到yield 结束
c.send("韭菜馅") #发送数据给生成器第二次执行 输出语句,然后进入循环 碰到yield 结束
迭代器
- 迭代对象:可以用于for循环的对象成为迭代对象(Iteralbe),如:list,tuple,dict,set,str和生成器等。
- 迭代器:可以被next函数调用并不断返回下一个值的对象成为迭代器(Iterator)
基本函数
- 是否是迭代对象(导入模块后用isinstance函数判读):
from collections import Iterable,Iterator
print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({"name","domain"},Iterable))
print(isinstance("domain",Iterable))
print(isinstance(123,Iterable))
- 是否是迭代器(导入模块后用isinstance函数判读):
from collections import Iterable,Iterator
print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({"name","domain"},Iterator))
print(isinstance("domain",Iterator))
print(isinstance(123,Iterator))
- 非迭代器(可迭代对象)变成迭代器,用iter函数:
a=[1,2,3]
b=iter(a)
b.__next__()
扩展
- for 循环也是通过迭代器实现:
for x in range(10):
print(x)
break
等价于:
it = iter([0,1,2,3,4,5,6,7,8,9])
while True:
try:
x=it.__next__()
print(x)
except:
break
- 文件的读取也是通过迭代器实现:
for f in f:
print(f)
更多最新Python教程资源关注微信公众号 凯撒网络研究院,回复 Python获取。