zoukankan      html  css  js  c++  java
  • 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/

  • 相关阅读:
    解析网页源码方式
    vue踩坑--细节决定成败
    fallowing-travelvue
    学会不怕
    eslint代码规范检测
    三次握手+四次挥手
    小白的学习笔记
    es6数组
    css知识整理
    JavaScript之事件循环,宏任务与微任务
  • 原文地址:https://www.cnblogs.com/niuxichuan/p/6653509.html
Copyright © 2011-2022 走看看