Created
January 6, 2023 15:59
-
-
Save jsbueno/e4378521ead8f9dbb40565fb5cacd0b9 to your computer and use it in GitHub Desktop.
Snippets for advanced generator research I used when figuring out an answer for https://stackoverflow.com/questions/74922314/yield-from-vs-yield-in-for-loop
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class VerboseItBase: | |
def __new__(cls, gen, method): | |
if method == "from": | |
cls = VerboseItFrom | |
elif method == "explicit": | |
cls = VerboseItExplicit | |
return super().__new__(cls) | |
def __init__(self, gen, method): | |
self.gen = gen | |
self.method = method | |
def __iter__(self): | |
print("verbose iter called for 'classic'") | |
try: | |
for item in self.gen: | |
yield item | |
except GeneratorExit: | |
print("generator exit thrown in intermediate gen. 'classic'") | |
raise | |
def close(self): | |
print("close in intermediate iterator called") | |
# Explictly do not forward close for testing purposes: | |
# self.gen.close() | |
def __del__(self): | |
print("intermediate iterator __del__") | |
try: | |
super().__del__() | |
except AttributeError: | |
pass | |
VerboseIt = VerboseItBase | |
class VerboseItExplicit(VerboseItBase): | |
def __iter__(self): | |
print("verbose iter called for 'explict'") | |
return self | |
def throw(self, *args): | |
print(args) | |
def __next__(self): | |
print("intermediate __next__ called") | |
return next(self.gen) | |
class VerboseItFrom(VerboseItBase): | |
def __iter__(self): | |
print("verbose iter called for 'yield from'") | |
try: | |
yield from self.gen | |
except GeneratorExit: | |
print("generator exit thrown in intermediate gen. 'from'") | |
raise | |
return | |
class Test: | |
def __init__(self, gen, method): | |
self.gen = gen | |
self.method = method | |
def __iter__(self): | |
return iter(VerboseIt(self.gen, self.method)) | |
first = lambda i: next(iter(i)) | |
a = Test((i for i in range(3)), "") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment