Iterator、Generator、Decorator、Descriptor

Python中的迭代器、生成器、装饰器、描述符。

可迭代对象(iterable)
但凡是可以返回一个迭代器的对象都可成为可迭代对象
可迭代对象实现了__iter__方法,该方法返回一个迭代器对象
迭代器(iterator)
迭代器是一个带状态的对象
迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator
任何实现了__iter__和__next__方法的对象都是迭代器
__iter__返回迭代器自身,__next__返回容器中的下一个值

 1 class Fib:
 2     def __init__(self):
 3         self.cur = 1
 4         self.pre = 0
 5     def __iter__(self):
 6         return self
 7     def __next__(self):
 8         value = self.cur
 9         self.cur += self.pre
10         self.pre = value
11         return value
12 f = Fib()
13 list(islice(f, 0, 10))

Fib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(因为实现了__next__方法)。实例变量prev和curr用户维护迭代器内部的状态。

生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写__iter__()__next__()方法了,只需要一个yiled关键字。

生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。

def Fib():
    pre, cur = 0, 1
    while True:
        yield cur
        pre, cur = cur, pre + cur
f = Fib()
list(islice(f, 0, 10))

#生成器表达式
a = (x * x for x in range(10))

 reference:https://foofish.net/iterators-vs-generators.html

装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数。

def outer(some_func):
    def inner():
        print('before some_func')
        ret = some_func()
        return ret + 1
    return inner
def foo():
    return 1
decorated = outer(foo)

class Coordinate(object):
    def __init__(self, x, y):
        self.x = x;
        self.y = y;
    def __repr__(self):
        return "Coord:" + str(self.__dict__)
def add(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)
def sub(a, b):
    return Coordinate(a.x - b.x, a.y - b.y)

def wrapper(func):
    def checker(a, b):
        if a.x < 0 or a.y < 0:
            a = Coordinate(a.x if a.x > 0 else 0, a.y if a.y > 0 else 0)
        if b.x < 0 or b.y < 0:
            b = Coordinate(b.x if b.x > 0 else 0, b.y if b.y > 0 else 0)
        ret = func(a, b)
        if ret.x < 0 or ret.y < 0:
            ret = Coordinate(ret.x if ret.x > 0 else 0, ret.y if ret.y > 0 else 0)
        return ret
    return checker

add = wrapper(add)
sub = wrapper(sub)

@wrapper
def add(a, b):
    return Coordinate(a.x + b.x, a.y + b.y)

def logger(func):
    def inner(*args, **kwargs):
        print('Arguments were: {0}, {1}'.format(args, kwargs))
        return func(*args, **kwargs)
    return inner

@logger
def foo(x, y = 10):
    return x ** y
foo(3, 10)

reference:http://python.jobbole.com/81683/

原文地址:https://www.cnblogs.com/niuxichuan/p/6653509.html