What is the difference between profitability and profitability in python 3.3.2+

After python 3.3.2+ python supports the new syntax for creating a generator function

yield from <expression>

I quickly tried to do it

>>> def g():
...     yield from [1,2,3,4]
...
>>> for i in g():
...     print(i)
...
1
2
3
4
>>>

Seems easy to use, but the PEP document is complex. My question is, is there any other difference compared to the previous release? Thanks.

+4
source share
3 answers

For most applications, it yield fromsimply prints everything left and back in order:

def iterable1():
    yield 1
    yield 2

def iterable2():
    yield from iterable1()
    yield 3

assert list(iterable2) == [1, 2, 3]

For 90% of users who see this post, I assume that for them this will be enough explanation. yield fromjust delegates iterability on the right side.


Coroutines

, , . , . , , :

def coroutine():
    x = yield None
    yield 'You sent: %s' % x

c = coroutine()
next(c)
print(c.send('Hello world'))

: , ( ). contextlib.contextmanager. . , , API- google app-engine ndb API datastore .

, send , ... ? , python2.x, :

def python2_generator_wapper():
    for item in some_wrapped_generator():
        yield item

, :

def python2_coroutine_wrapper():
    """This doesn't work.  Somebody smarter than me needs to fix it. . .

    Pain.  Misery. Death lurks here :-("""
    # See https://www.python.org/dev/peps/pep-0380/#formal-semantics for actual working implementation :-)
    g = some_wrapped_generator()
    for item in g:
        try:
            val = yield item
        except Exception as forward_exception:  # What exceptions should I not catch again?
            g.throw(forward_exception)
        else:
            if val is not None:
                g.send(val)  # Oops, we just consumed another cycle of g ... How do we handle that properly ...

yield from:

def coroutine_wrapper():
    yield from coroutine()

yield from (!) .


, PEP . OP, , . python2.x :

def iterable():
    yield 'foo'
    return 'done'

a SyntaxError. yield . , - (. ). , (, ?), . , StopIteration ( ), StopIteration . , :

 raise StopIteration('done')

- , .

+14

yield from :

def generator1():
    for item in generator2():
        yield item
    # do more things in this generator

:

def generator1():
    yield from generator2()
    # more things on this generator

-: yield from , , , .

, - , , , , - , -

, :

def func1():
    # some calculation
    for i in somesequence:
        # complex calculation using i 
        # ...
        # ...
        # ...
    # some more code to wrap up results
    # finalizing
    # ...

, :

def func2(i):
    # complex calculation using i 
    # ...
    # ...
    # ...
    return calculated_value

def func1():
    # some calculation
    for i in somesequence:
         func2(i)
    # some more code to wrap up results
    # finalizing
    # ...

def generator1():
    for item in generator2():
        yield item
    # do more things in this generator

for item in generator1():
    # do things

, , generator2, generator1, , cotnext generator2 - , 1, , .

, , , : , , , .

"" , : , . , https://www.python.org/dev/peps/pep-3156/, , , (- , ) - yield from - , ( mainloop - , ). , , .

, , . , ​​ , (, ) .

, - :

@asyncio.coroutine
def crawler(url):
   page_content = yield from async_http_fetch(url)
   urls = parse(page_content)
   ...

html- asyncio.

Python 3.4 asyncio stdlib . , Python 3.5 , , . https://www.python.org/dev/peps/pep-0492/

+7

Here is an example that illustrates this:

>>> def g():
...     yield from range(5)
... 
>>> list(g())
[0, 1, 2, 3, 4]
>>> def g():
...     yield range(5)
... 
>>> list(g())
[range(0, 5)]
>>>

yield fromgives each element iterable, but yieldgives iterable itself.

0
source

Source: https://habr.com/ru/post/1629654/


All Articles