标签: yield-from

将"yield from"语句转换为Python 2.7代码

我在Python 3.2中有一个代码,我想在Python 2.7中运行它.我确实转换了它(已经把missing_elements两个版本的代码都放了)但我不确定这是否是最有效的方法.基本上如果yield frommissing_element功能的上半部分和下半部分有两个如下所示的调用会发生什么?两个部分(上部和下部)中的条目是否在一个列表中相互附加,以便父级递归函数与yield from调用一起使用并将两个部分一起使用?

def missing_elements(L, start, end):  # Python 3.2
    if end - start <= 1: 
        if L[end] - L[start] > 1:
            yield from range(L[start] + 1, L[end])
        return

index = start + (end - start) // 2

# is the lower half consecutive?
consecutive_low =  L[index] == L[start] + (index - start)
if not consecutive_low:
    yield from missing_elements(L, start, index)

# is the upper part consecutive?
consecutive_high =  L[index] …
Run Code Online (Sandbox Code Playgroud)

python yield generator python-2.x yield-from

66
推荐指数
4
解决办法
3万
查看次数

yield from 与 for 循环中的yield

我的理解yield from是,它类似于yield从可迭代对象中获取每个项目。然而,我在以下示例中观察到不同的行为。

我有Class1

class Class1:
    def __init__(self, gen):
        self.gen = gen
        
    def __iter__(self):
        for el in self.gen:
            yield el
Run Code Online (Sandbox Code Playgroud)

和 Class2 的不同之处仅在于yield将 for 循环替换为yield from

class Class2:
    def __init__(self, gen):
        self.gen = gen
        
    def __iter__(self):
        yield from self.gen
Run Code Online (Sandbox Code Playgroud)

下面的代码从给定类的实例中读取第一个元素,然后在 for 循环中读取其余元素:

a = Class1((i for i in range(3)))
print(next(iter(a)))
for el in iter(a):
    print(el)
Run Code Online (Sandbox Code Playgroud)

Class1这会为和产生不同的输出Class2。对于Class1输出是

0
1
2
Run Code Online (Sandbox Code Playgroud)

Class2输出为

0
Run Code Online (Sandbox Code Playgroud)

现场演示

yield from产生不同行为的背后机制是什么?

python yield generator python-internals yield-from

31
推荐指数
1
解决办法
2823
查看次数

从流中产生的正确方法是什么?

我有一个Connection用于包含读取和写入asyncio连接流的对象:

class Connection(object):

    def __init__(self, stream_in, stream_out):
        object.__init__(self)

        self.__in = stream_in
        self.__out = stream_out

    def read(self, n_bytes : int = -1):
        return self.__in.read(n_bytes)

    def write(self, bytes_ : bytes):
        self.__out.write(bytes_)
        yield from self.__out.drain()
Run Code Online (Sandbox Code Playgroud)

在服务器端,每次客户端连接时connected创建一个Connection对象,然后读取4个字节.

@asyncio.coroutine
def new_conection(stream_in, stream_out):
    conn = Connection(stream_in, stream_out)
    data = yield from conn.read(4)
    print(data)
Run Code Online (Sandbox Code Playgroud)

在客户端,写出4个字节.

@asyncio.coroutine
def client(loop):
    ...
    conn = Connection(stream_in, stream_out)
    yield from conn.write(b'test')
Run Code Online (Sandbox Code Playgroud)

这个作品几乎为预期的,但我必须yield from每天readwrite电话.我yield from从里面尝试过Connection: …

python generator python-3.x python-asyncio yield-from

23
推荐指数
1
解决办法
1322
查看次数

"从迭代中获得"vs"返回iter(可迭代)"

在包装(内部)迭代器时,通常必须将__iter__方法重新路由到底层的iterable.请考虑以下示例:

class FancyNewClass(collections.Iterable):
    def __init__(self):
        self._internal_iterable = [1,2,3,4,5]

    # ...

    # variant A
    def __iter__(self):
        return iter(self._internal_iterable)

    # variant B
    def __iter__(self):
        yield from self._internal_iterable
Run Code Online (Sandbox Code Playgroud)

变体A和B之间是否有任何显着差异?Variant A返回iter()已从内部iterable中查询过的迭代器对象.变量B返回一个生成器对象,该对象返回内部可迭代的值.出于某种原因,是其中一种还是其他的?在collections.abcyield from版本中使用.该return iter()变种是,我已经使用到现在的格局.

python iterable python-3.x yield-from

21
推荐指数
1
解决办法
1124
查看次数

`from foo()`和`for f in foo()之间的区别:yield x`

在Python中,大多数收益率的例子都说明了这一点

yield from foo()
Run Code Online (Sandbox Code Playgroud)

类似于

for x in foo(): yield x
Run Code Online (Sandbox Code Playgroud)

另一方面它似乎并不完全相同,并且有一些魔法投入.我觉得使用一个我不理解的魔法函数有点不安.我有什么必须知道的,yield from以避免陷入魔法做我不期望的事情的魔力?我应该注意到魔法提供了哪些优势?

python yield generator python-3.x yield-from

12
推荐指数
1
解决办法
226
查看次数

`yield from $ generator`和`return $ generator`之间的区别?

我有一个功能,返回一个发电机.目前它使用yield from:

function foo()
{
    $generator = getGenerator();
    // some other stuff (no yields!)
    yield from $generator;
}
Run Code Online (Sandbox Code Playgroud)

如果我yield from用一个简单的替换它,return在这种情况下,这会改变什么吗?也许在执行中?还是表现?会yield from产生一个新的"外部"迭代器吗?

我知道,在其他情况下yield from可以更灵活,因为我可以使用它几次甚至将它与简单的yields 混合,但这对我的情况无关紧要.

php return generator yield-from

12
推荐指数
2
解决办法
3180
查看次数

如何截取生成器的第一个值并透明地从其余值中产生

更新:我已经启动了一个关于 python-ideas线程来为此目的提出额外的语法或 stdlib 函数(即指定由 发送的第一个值yield from)。到目前为止 0 回复...:/


如何拦截子生成器的第一个生成值,但使用 将迭代的其余部分委托给后者yield from

例如,假设我们有一个任意的双向生成器subgen,我们想将它包装在另一个生成器中gen。的目的gen是拦截第一个subgen生成的值,并将生成的其余部分(包括发送的值、抛出的异常、.close() 等)委托给子生成器。

可能会想到的第一件事可能是这样的:

def gen():
    g = subgen()

    first = next(g)
    # do something with first...
    yield "intercepted"

    # delegate the rest
    yield from g
Run Code Online (Sandbox Code Playgroud)

但这是错误的,因为当调用者.send在获得第一个值后将某些东西返回给生成器时,它最终会作为yield "intercepted"表达式的值被忽略,而是作为第一个值g接收,作为语义的一部分的。None.sendyield from

所以我们可能会想这样做:

def gen():
    g = subgen()

    first = next(g)
    # do …
Run Code Online (Sandbox Code Playgroud)

python generator yield-from

12
推荐指数
1
解决办法
363
查看次数

从返回值修改收益率

假设我有这些解析器:

parsers = {
    ".foo": parse_foo,
    ".bar", parse_bar
}
Run Code Online (Sandbox Code Playgroud)

parse_foo并且parse_bar都是逐个产生行的生成器.如果我想创建一个调度函数,我会这样做:

def parse(ext):
    yield from parsers[ext]()
Run Code Online (Sandbox Code Playgroud)

语法的收益使我能够轻松地在生成器上下传递信息.

有没有办法在修改产量结果的同时保持隧道效应?
在破坏隧道时这样做很容易:

def parse(ext):
    for result in parsers[ext]():
        # Add the extension to the result
        result.ext = ext
        yield result
Run Code Online (Sandbox Code Playgroud)

但这种方式我无法使用.send().throw()一直到解析器.

我想到的唯一方法是做一些丑陋的事情try: ... except Exception: ...并将异常传递出去,同时做同样的事情.send().它很难看,很杂乱,容易出错.

python generator python-3.x yield-from

7
推荐指数
1
解决办法
323
查看次数

“yield from”可以与哪些对象一起使用?

最初(PEP 380),yield from引入了语法以用于委托给“子生成器”。后来它与现在已弃用的基于生成器的协程一起使用。

我不知道yield from一般可以应用什么样的对象。我的第一个猜想是它只需要__iter__对象上的方法来返回迭代器。实际上,以下适用于 Python 3.8:

class C:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        return iter(range(self.n))

def g(n):
    yield from C(n)

print(tuple(g(3)))
Run Code Online (Sandbox Code Playgroud)

但是,它也适用于一些asyncio.sleep(1)没有__iter__方法的等待对象,例如。

一般规则是什么?是什么决定了一个对象是否可以作为yield fromform的参数给出?

python generator coroutine python-3.x yield-from

6
推荐指数
1
解决办法
81
查看次数

为什么嵌套"yield from"语句(生成器委托)会产生终止的"None"值?

是否可以嵌套yield from语句?

简单的形式是显而易见的:

def try_yield1():
    x = range(3)
    yield from x
Run Code Online (Sandbox Code Playgroud)

哪个产生:

0
1
2
Run Code Online (Sandbox Code Playgroud)

但是,如果我有嵌套的生成器怎么办?

def try_yield_nested():
   x = [range(3) for _ in range(4)]
    yield from ((yield from y) for y in x)
Run Code Online (Sandbox Code Playgroud)

这会产生:

0
1
2
None # why?
0
1
2
None # ...
0
1
2
None # ...
Run Code Online (Sandbox Code Playgroud)

None如果我使用yield from它(为什么它是嵌套的)它为什么会产生?

我知道我可以这样做:

from itertools import chain

def try_yield_nested_alternative():
    x = [range(3) for _ in range(4)]
    yield from chain.from_iterable(x)
Run Code Online (Sandbox Code Playgroud)

这产生相同的输出而忽略了None(这是我期望的).我也可以写一个简单的循环: …

python yield generator python-3.x yield-from

5
推荐指数
1
解决办法
155
查看次数