I was working with generator functions and private functions of a class. I am wondering
- Why when yielding (which in my one case was by accident) in __someFunc that this function just appears not to be called from within __someGenerator. Also what is the terminology I want to use when referring to these aspects of the language?
- Can the python interpreter warn of such instances?
Below is an example snippet of my scenario.
class someClass():
def __init__(self):
pass
#Copy and paste mistake where yield ended up in a regular function
def __someFunc(self):
print "hello"
#yield True #if yielding in this function it isn't called
def __someGenerator (self):
for i in range(0, 10):
self.__someFunc()
yield True
yield False
def someMethod(self):
func = self.__someGenerator()
while func.next():
print "next"
sc = someClass()
sc.someMethod()
I got burned on this and spent some time trying to figure out why a function just wasn’t getting called. I finally discovered I was yielding in function I didn’t want to in.
I’ll try to answer the first of your questions.
A regular function, when called like this:
executes its inside statements until it ends or a
returnstatement is reached. Then the return value of the function is assigned toval.If a compiler recognizes the function to actually be a generator and not a regular function (it does that by looking for
yieldstatements inside the function — if there’s at least one, it’s a generator), the scenario when calling it the same way as above has different consequences. Upon callingfunc(), no code inside the function is executed, and a special<generator>value is assigned toval. Then, the first time you callval.next(), the actual statements offuncare being executed until ayieldorreturnis encountered, upon which the execution of the function stops, value yielded is returned and generator waits for another call toval.next().That’s why, in your example, function
__someFuncdidn’t print “hello” — its statements were not executed, because you haven’t calledself.__someFunc().next(), but onlyself.__someFunc().Unfortunately, I’m pretty sure there’s no built-in warning mechanism for programming errors like yours.