DEV Community

Super Kai (Kazuya Ito)
Super Kai (Kazuya Ito)

Posted on

Generator in Python (3)

Buy Me a Coffee

*Memo:

A yield statement can be assigned to a variable to be used with or without send() as shown below:

*Memo:

  • send() starts or resumes the generator, sends a value into the variable assigned a yield statement only when resuming the generator, executes a yield statement to return a value and pauses the generator or raises StopIteration if the generator is terminated:
    • The 1st argument is value(Required-Type:Any):
      • It must be None when starting the generator.
      • Don't use value=.
  • The variable assigned a yield statement has None by default.
  • yield from only with a generator(yield from generator) works with send() properly.

<yield without send()>:

def gen():
    a = yield 0
    print(a, 'gen')
    b = yield 1
    print(b, 'gen')
    c = yield 2
    print(c, 'gen')

v = gen()

print(next(v)) # 0
print(next(v)) # None gen
               # 1
print(next(v)) # None gen
               # 2
print(next(v)) # None gen
               # StopIteration:
Enter fullscreen mode Exit fullscreen mode

<yield with send()>:

def gen():
    a = yield 0
    print(a, 'gen')
    b = yield 1
    print(b, 'gen')
    c = yield 2
    print(c, 'gen')

v = gen()

print(v.send(None)) # 0
print(v.send('A'))  # A gen
                    # 1
print(v.send('B'))  # B gen
                    # 2
print(v.send('C'))  # C gen
                    # StopIteration:
Enter fullscreen mode Exit fullscreen mode
def gen():
    a = yield 0
    print(a, 'gen')
    b = yield 1
    print(b, 'gen')
    c = yield 2
    print(c, 'gen')

v = gen()

print(v.send('A'))
# TypeError: can't send non-None value to a just-started generator
Enter fullscreen mode Exit fullscreen mode

<yield from without send()>:

def gen():
    a = yield from [0, 1]
    print(a, 'gen')
    b = yield from [2, 3]
    print(b, 'gen')
    c = yield from [4, 5]
    print(c, 'gen')

v = gen()

print(next(v)) # 0
print(next(v)) # 1
print(next(v)) # None gen
               # 2
print(next(v)) # 3
print(next(v)) # None gen
               # 4
print(next(v)) # 5
print(next(v)) # None gen
               # StopIteration:
Enter fullscreen mode Exit fullscreen mode

<yield from with send()>:

def sub_gen():
    a = yield 0
    print(a, 'sub_gen')
    b = yield 1
    print(b, 'sub_gen')
    c = yield 2
    print(c, 'sub_gen')

def gen():
    d = yield from sub_gen()
    print(d, 'gen')

v = gen()

print(v.send(None)) # 0
print(v.send('A'))  # A sub_gen
                    # 1
print(v.send('B'))  # B sub_gen
                    # 2
print(v.send('C'))  # C sub_gen
                    # None gen
                    # StopIteration:
Enter fullscreen mode Exit fullscreen mode
def gen():
    a = yield from [0, 1]
    print(a, 'gen')
    b = yield from [2, 3]
    print(b, 'gen')
    c = yield from [4, 5]
    print(c, 'gen')

v = gen()

print(v.send('A'))
# TypeError: can't send non-None value to a just-started generator
Enter fullscreen mode Exit fullscreen mode
def gen():
    a = yield from [0, 1]
    print(a, 'gen')
    b = yield from [2, 3]
    print(b, 'gen')
    c = yield from [4, 5]
    print(c, 'gen')

v = gen()

print(v.send(None)) # 0
print(v.send('A'))
# AttributeError: 'list_iterator' object has no attribute 'send'
Enter fullscreen mode Exit fullscreen mode

A yield statement cannot be assigned to a for statement as shown below:

def gen():
    for a in yield [0, 1, 2]:
    # for a in yield from [0, 1, 2]:
        print(v)
# SyntaxError: invalid syntax
Enter fullscreen mode Exit fullscreen mode

Top comments (0)