我的python学习(六) 迭代器、闭包、装饰器

迭代器

如何判断一个对象是否可迭代?

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   #缓存了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值