How to identify generator/iterator objects?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Kenneth McDonald

    How to identify generator/iterator objects?

    I'm trying to write a 'flatten' generator which, when give a
    generator/iterator that can yield iterators, generators, and other data
    types, will 'flatten' everything so that it in turns yields stuff by
    simply yielding the instances of other types, and recursively yields the
    stuff yielded by the gen/iter objects.

    To do this, I need to determine (as fair as I can see), what are
    generator and iterator objects. Unfortunately:
    >>iter("abc")
    <iterator object at 0x61d90>
    >>def f(x):
    .... for s in x: yield s
    ....
    >>f
    <function f at 0x58230>
    >>f.__class__
    <type 'function'>

    So while I can identify iterators, I can't identify generators by class.

    Is there a way to do this? Or perhaps another (better) way to achieve
    this flattening effect? itertools doesn't seem to have anything that
    will do it.

    Thanks,
    Ken
  • Paddy

    #2
    Re: How to identify generator/iterator objects?


    Kenneth McDonald wrote:
    I'm trying to write a 'flatten' generator which, when give a
    generator/iterator that can yield iterators, generators, and other data
    types, will 'flatten' everything so that it in turns yields stuff by
    simply yielding the instances of other types, and recursively yields the
    stuff yielded by the gen/iter objects.
    >
    To do this, I need to determine (as fair as I can see), what are
    generator and iterator objects. Unfortunately:
    >
    >>iter("abc")
    <iterator object at 0x61d90>
    >>def f(x):
    ... for s in x: yield s
    ...
    >>f
    <function f at 0x58230>
    >>f.__class__
    <type 'function'>
    >
    So while I can identify iterators, I can't identify generators by class.
    >
    Is there a way to do this? Or perhaps another (better) way to achieve
    this flattening effect? itertools doesn't seem to have anything that
    will do it.
    >
    Thanks,
    Ken
    >>def f(x):
    .... for s in x: yield s
    ....
    >>f([1])
    <generator object at 0x01388E18>

    ?
    - Paddy.

    Comment

    • Leo Kislov

      #3
      Re: How to identify generator/iterator objects?


      Kenneth McDonald wrote:
      I'm trying to write a 'flatten' generator which, when give a
      generator/iterator that can yield iterators, generators, and other data
      types, will 'flatten' everything so that it in turns yields stuff by
      simply yielding the instances of other types, and recursively yields the
      stuff yielded by the gen/iter objects.
      >
      To do this, I need to determine (as fair as I can see), what are
      generator and iterator objects. Unfortunately:
      >
      >>iter("abc")
      <iterator object at 0x61d90>
      >>def f(x):
      ... for s in x: yield s
      ...
      >>f
      <function f at 0x58230>
      >>f.__class__
      <type 'function'>
      >
      So while I can identify iterators, I can't identify generators by class.
      But f is not a generator, it's a function returning generator:
      >>def f():
      .... print "Hello"
      .... yield 1
      ....
      >>iter(f)
      Traceback (most recent call last):
      File "<input>", line 1, in ?
      TypeError: iteration over non-sequence
      >>iter(f())
      <generator object at 0x016C7238>
      >>type(f())
      <type 'generator'>
      >>>
      Notice, there is no side effect of calling f function.

      -- Leo

      Comment

      • Martin v. Löwis

        #4
        Re: How to identify generator/iterator objects?

        Kenneth McDonald schrieb:
        To do this, I need to determine (as fair as I can see), what are
        Is there a way to do this? Or perhaps another (better) way to achieve
        this flattening effect? itertools doesn't seem to have anything that
        will do it.
        As others have pointed out, there is a proper test for generator
        objects; you are apparently interested in finding out whether a
        function will produce a generator when called.

        To do that, use the following code

        def is_generator_fu nction(f):
        return (f.func_code.co _flags & 0x20) != 0

        Here, 0x20 is the numeric value of CO_GENERATOR (also available
        through compiler.consts .CO_GENERATOR).

        Regards,
        Martin

        Comment

        • Paddy

          #5
          Re: How to identify generator/iterator objects?


          Kenneth McDonald wrote:
          I'm trying to write a 'flatten' generator which, when give a
          generator/iterator that can yield iterators, generators, and other data
          types, will 'flatten' everything so that it in turns yields stuff by
          simply yielding the instances of other types, and recursively yields the
          stuff yielded by the gen/iter objects.
          >
          To do this, I need to determine (as fair as I can see), what are
          generator and iterator objects. Unfortunately:
          >
          >>iter("abc")
          <iterator object at 0x61d90>
          >>def f(x):
          ... for s in x: yield s
          ...
          >>f
          <function f at 0x58230>
          >>f.__class__
          <type 'function'>
          >
          So while I can identify iterators, I can't identify generators by class.
          >
          Is there a way to do this? Or perhaps another (better) way to achieve
          this flattening effect? itertools doesn't seem to have anything that
          will do it.
          >
          Thanks,
          Ken
          Unfortunately, nothing is as easy as it may seem:
          >>def is_generator(f) :
          .... return f.func_code.co_ flags & CO_GENERATOR != 0
          ....
          >>def f(x):
          .... for s in x: yield s
          ....
          >>is_generator( f)
          True
          >># But look at the following:
          >>def f2(x):
          .... def g(y):
          .... for s in y: yield s
          .... return g(x)
          ....
          >>f2([1,2,3])
          <generator object at 0x013DEC88>
          >>is_generator( f2)
          False
          >>>
          ;-)

          - Paddy.

          Comment

          Working...