python的【yield from】【yield 】【with】【@contextlib.contextmanager】混合【使用缺陷】

  1. yield from 【Python3.5后被代替】
https://www.jianshu.com/p/87da832730f5
Python3.3之后引入了新语法yield from 
Python3.5开始引入了新的语法 async 和 await ,而await替代的就是yield from(为了不与实现内层for循环的yield from误解)

# 如果生成器函数需要产出另一个生成器生成的值,传统的解决方法是使用嵌套的for循环:
>>> def chain(*iterables):
...     for it in iterables:
...         for i in it:
...             yield i
>>> s = 'ABC'
>>> t = tuple(range(3))
>>> list(chain(s, t))
['A', 'B', 'C', 0, 1, 2]


# 使用yield from 方法
>>> def chain(*iterables):
...     for i in iterables:
...         yield from i
...
>>> list(chain(s, t))
['A', 'B', 'C', 0, 1, 2]



# 经典的例子【处理嵌套,返回没有嵌套的单值序列】
from collections.abc import Iterable

def flatten(items, ignore_types=(str, bytes)):
    for x in items:
        if isinstance(x, Iterable) and not isinstance(x, ignore_types):
            yield from flatten(x)
        else:
            yield x

items = [1, 2, [3, 4, [5, 6], 7], 8]
for x in flatten(items):
    print(x)

items = ['Dave', 'Paula', ['Thomas', 'Lewis']]
for x in flatten(items):
    print(x)
  1. enter】【exit】【with】

class DatabaseConnection(object):

    def __enter__(self):
        # make a database connection and return it
        ...
        return self.dbconn

    def __exit__(self, exc_type, exc_val, exc_tb):
        # make sure the dbconnection gets closed
        self.dbconn.close()
        ...


with DatabaseConnection() as mydbconn:  # 使用方法,with 对象(class())
    # do stuff
  1. 使用【@contextlib.contextmanager】【with】
import contextlib
import time

@contextlib.contextmanager
def timeit():
    start = time.time()
    print('before yield ')
    yield start                   # 理解 yield start执行完后返回,如果是 res = yield start ,那么赋值操作不会执行,# yield 在等式的右边,执行完就返回了,没有进行赋值 ;类似于 a = return 1【return这样用非法】,a 是NONE
    print('after yield stating')
    end = time.time()
    usedTime = (end - start) * 1000
    print ('Use time %d ms' % usedTime)
    print('after yield ending')

with timeit() as stattime:   # with timeit()  ,注意可以用as的情况
    print('in with staring')
    time.sleep(1)
    print('in with doing something')
    print('in with ending')

'''
结果:
before yield 
in with staring
in with doing something
in with ending
after yield stating
Use time 1000 ms
after yield ending
'''
原文地址:https://www.cnblogs.com/amize/p/14783817.html