day13.装饰器进阶,迭代器

1.from functools import wraps

这个函数可以保留原来函数的属性

# from functools import wraps
def car_time(fun):
    # @wraps(fun)
    def inner(*args,**kwargs):
        ret = fun(*args,**kwargs)
        return ret
    return inner

@car_time
def car(some):
    """ 这是一个函数car的注释"""
    print(some)
    print(car.__name__)
    print(car.__doc__)

car('hello')

  hello
  inner
  None

在这是掉functools模块的调用以后,可以看出,我们调用的函数 car() 实际是闭包函数里面的inner()函数。如果加入functools模块呢

from functools import wraps
def car_time(fun):
    @wraps(fun)
    def inner(*args,**kwargs):
        print('装饰前')
        ret = fun(*args,**kwargs)
        print('装饰后')
        return ret
    return inner

@car_time
def car(some):
    """ 这是一个函数car的注释"""
    print(some)
    print(car.__name__)
    print(car.__doc__)

car('hello')
装饰前
hello
car
 这是一个函数car的注释
装饰后

亲爱的詹姆斯先生,神不知鬼不觉的给你加了个装饰器。没改变函数的任何属性,岂不是美滋滋?我们用了都说好

带参数的装饰器

在装饰器外面再加一层函数,三层函数调用。

def outer(形参):
    def wrapper(func):
        def inner(*args,**kwargs):
            ret = func(*args,**kwargs)   # func是被装饰的函数 在这里被调用
            return ret
        return inner
    return wrapper

@outer(实参)
def func():
    pass

多个装饰器装饰一个函数

这个有空再补。。。

迭代器

小定义:只要含有 __iter__ 方法都是可迭代的,内部含有 __next__ 和 __iter__ 方法就是迭代器。

l1 = 'abc'
l2 = [1,2,3]
l3 = {}
print(l1.__iter__())
print(l2.__iter__())
print(l3.__iter__())

<str_iterator object at 0x000001B7BEF0BDA0>
<list_iterator object at 0x000001B7BEF0BE80>
<dict_keyiterator object at 0x000001B7BD2487C8>

这些可迭代的字符串,列表,字典等,执行了 __iter__() 方法,就是一个迭代器

l2 = [1,2,3,4,5]
l3 = l2.__iter__()
print(l3.__next__())
print(l3.__next__())
print(l3.__next__())
print(l3.__next__())
print(l3.__next__())
1
2
3
4
5

对迭代器执行__next__()方法,便可以取出迭代器的一个一个的值

from collections import Iterable
from collections import Iterator
class ABC:
    def __iter__(self):pass
    def __next__(self):pass

a = ABC()
print(isinstance(a,Iterable))
print(isinstance(a,Iterator))
True
True

此处我们定义一个类,给他__iter__() 和  __next__()  方法。isinstance()函数判断已知函数是否是已知的类型

简单的小结一下:

# 迭代器协议和可迭代协议
# 可以被for循环的都是可迭代的
# 可迭代的内部都有__iter__方法
# 只要是迭代器 一定可迭代
# 可迭代的.__iter__()方法就可以得到一个迭代器
# 迭代器中的__next__()方法可以一个一个的获取值

# for循环就是在使用迭代器

 

posted @ 2019-02-28 16:07  恶灵酒  阅读(174)  评论(0编辑  收藏  举报