笔记-pytho-语法-yield

笔记-python-语法-yield

1.      yield

1.1.    yield基本使用

def fab(max):

    n,a,b = 0, 0, 1

    while n < max:

        yield b

        a, b = b, a+b

        n = n + 1

f = fab(7)

print(f)

for i in f:

print(i)

1.2.    解释

在python 语法参考6.2.9中是这样描述的:

The yield expression is used when defining a generator function or an asynchronous generator function and thus can only be used in the body of a function definition. Using a yield expression in a function’s body causes that function to be a generator, and using it in an async def function’s body causes that coroutine function to be an asynchronous generator. 

当一个生成器函数被调用时,它返回一个生成器(迭代器);

当它暂停时,会保存

all local state, including the current bindings of local variables, the instruction pointer, the internal evaluation stack, and the state of any exception handling. 

1.3.    Generator-iterator methods

下面的章节描述了生成迭代器的方法,使用它们可以控制生成器函数的行为。

Note that calling any of the generator methods below when the generator is already executing raises a ValueErrorexception.

generator.__next__()

Starts the execution of a generator function or resumes it at the last executed yield expression. When a generator function is resumed with a __next__() method, the current yield expression always evaluates to None. The execution then continues to the next yield expression, where the generator is suspended again, and the value of the expression_list is returned to __next__()’s caller. If the generator exits without yielding another value, a StopIteration exception is raised.

This method is normally called implicitly, e.g. by a for loop, or by the built-in next() function.

generator.send(value)

Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value.

generator.throw(type[, value[, traceback]])

Raises an exception of type type at the point where the generator was paused, and returns the next value yielded by the generator function. If the generator exits without yielding another value, a StopIteration exception is raised. If the generator function does not catch the passed-in exception, or raises a different exception, then that exception propagates to the caller.

generator.close()

Raises a GeneratorExit at the point where the generator function was paused. If the generator function then exits gracefully, is already closed, or raises GeneratorExit (by not catching the exception), close returns to its caller. If the generator yields a value, a RuntimeError is raised. If the generator raises any other exception, it is propagated to the caller. close() does nothing if the generator has already exited due to an exception or normal exit.

1.4.  Examples

Here is a simple example that demonstrates the behavior of generators and generator functions:

>>> def echo(value=None):
...     print("Execution starts when 'next()' is called for the first time.")
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception as e:
...                 value = e
...     finally:
...         print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> print(next(generator))
Execution starts when 'next()' is called for the first time.
1
>>> print(next(generator))
None
>>> print(generator.send(2))
2
>>> generator.throw(TypeError, "spam")
TypeError('spam',)
>>> generator.close()
Don't forget to clean up when 'close()' is called.

1.5.    更多的案例

1.5.1.   example:1

def node._get_child_candidates(self, distance, min_dist, max_dist):

    if self._leftchild and distance - max_dist < self._median:

        yield self._leftchild

    if self._rightchild and distance + max_dist >= self._median:

        yield self._rightchild

1.5.2.   send案例

send有点不同

def func_yield():

    x = yield 8

    print(x)

    x = yield x+6

    print(x)

    x = yield 23

print(x)

return 14

   

a = func_yield()

print('step 1:')

print(a.send(None))

print('step 2:')

print(a.send(11))

print('step 3:')

print(a.send(12))

print(a.send(13))

输出:

step 1:

8

step 2:

11

17

step 3:

12

23

13

Traceback (most recent call last):

  File "E:\python\person_code\python_foundation\python_other.py", line 403, in <module>

    print(a.send(13))

StopIteration: 14

send是先执行赋值后执行yield,

或者说x=yield 7等于

yield 7

x = val

最后一定是抛出一个异常来结束。

猜你喜欢

转载自www.cnblogs.com/wodeboke-y/p/9940370.html
今日推荐