How can I tell whether a generator was just-started?

前端 未结 3 914
青春惊慌失措
青春惊慌失措 2020-12-28 12:49

I\'d like a function, is_just_started, which behaves like the following:

>>> def gen(): yield 0; yield 1
>>> a = gen()
>>         


        
3条回答
  •  南笙
    南笙 (楼主)
    2020-12-28 13:25

    This only works in Python 3.2+:

    >>> def gen(): yield 0; yield 1
    ... 
    >>> a = gen()
    >>> import inspect
    >>> inspect.getgeneratorstate(a)
    'GEN_CREATED'
    >>> next(a)
    0
    >>> inspect.getgeneratorstate(a)
    'GEN_SUSPENDED'
    >>> next(a)
    1
    >>> inspect.getgeneratorstate(a)
    'GEN_SUSPENDED'
    >>> next(a)
    Traceback (most recent call last):
      File "", line 1, in 
    StopIteration
    >>> inspect.getgeneratorstate(a)
    'GEN_CLOSED'
    

    So, the requested function is:

    import inspect
    
    def is_just_started(gen):
        return inspect.getgeneratorstate(gen) == inspect.GEN_CREATED:
    

    Out of curiosity, I looked into CPython to figure out how it was determining this... Apparently it looks at generator.gi_frame.f_lasti which is the "index of last attempted instruction in bytecode". If it's -1 then it hasn't started yet.

    Here's a py2 version:

    def is_just_started(gen):
        return gen.gi_frame is not None and gen.gi_frame.f_lasti == -1
    

提交回复
热议问题