迭代器
如何判断一个对象是否可迭代?
from collections import Iterable
isinstance(object,Iterable)
迭代器用起来非常灵巧,不仅可以迭代序列,也可以迭代表现出序列行为的对象,例如字典的键、一个文件的行,字符串,等等。
string = '1234567'
it = iter(string)
print(type(it))
#使用next方法访问
print(next(it))
print(next(it))
执行结果:
<class 'str_iterator'>
1
2
#迭代器迭代字典
a = {1:'a', 2:'b'}
it2 = iter(a)
print(next(it2))
执行结果:
1
2
闭包
闭包特点:1.函数内部嵌套了函数,2.函数的返回值是嵌套的内部函数
#例如
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
print("series in averager: ", series)
total = sum(series)
return total / len(series)
return averager
avg = make_averager() #make_averager()的返回值是averager(),这里相当于给averager()起了别名avg
print(avg(10)) #打印执行传了参数10的avg函数,结果为10,series列表里保存了10
print(avg(11)) #打印执行传了参数1,1的avg函数,结果为10.5,eries列表里保存了10、11
series 是一个自由变量(free variable),表明这个变量没有被绑定在局部作用域中,同时 averager函数的闭包行为使得它可以访问到这个自由变量。
series 是可变变量,在内部函数中使用时没有问题,如果是不可变变量,如 string、number、tuple 等,在内部函数引用则会报错。对于不可变的自由变量,如果想要在闭包内部修改它 就要加一个nonlocal
def outer_func():
list1 = [] #自由变量
mysum = 0 #不可变类型
def inner_func(name):
nonlocal mysum
mysum = mysum + 1
list1.append(len(list1) + 1)
print('%s, lis1:%s'%(name, list1))
print('inner_func_mysum:', mysum)
print('out_func_mysum:', mysum)
inner_func('name')
return inner_func
装饰器
python的装饰器就是用于拓展原来函数功能的一种函数,这个函数的返回值也是一个函数,使用python装饰器的好处就是在不用更改原函数的代码前提下给函数增加新的功能。
带有不定参数的装饰器
import time
def deco(func):
def wrapper(*args, **kwargs):
startTime = time.time()
func(*args, **kwargs)
endTime = time.time()
msecs = (endTime - startTime)*1000
print("time is %d ms" %msecs)
return wrapper
@deco
def func(a,b):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b))
@deco
def func2(a,b,c):
print("hello,here is a func for add :")
time.sleep(1)
print("result is %d" %(a+b+c))
多个装饰器执行的顺序就是从最后一个装饰器开始,执行到第一个装饰器,再执行函数本身。
例如:
def dec1(func):
print("1111")
def one():
print("2222")
func()
print("3333")
return one
def dec2(func):
print("aaaa")
def two():
print("bbbb")
func()
print("cccc")
return two
@dec1
@dec2
def test():
print("test test")
test()
执行结果:
aaaa
1111
2222
bbbb
test test
cccc
3333
函数缓存功能的装饰器
from functools import lru_cache
@lru_cache(maxsize=None,typed=True) #lru_cache(add)
def add(x, y):
print("calculating: %s - %s" % (x, y))
s=0
for i in range(int(x), int(y)):
s=s+i
return s
#lru_cache(maxsize=None,typed=False)(add)
res = add(1, 100)
print('计算结果res:', res)
res2 = add(1, 100)
print('计算结果res2:', res2)
#执行结果
calculating: 1 - 100
计算结果res: 4950
计算结果res2: 4950 #缓存了