generator testing and attrs

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

    generator testing and attrs

    I need to be able to store a list of schedulable items, either regular
    callables or generator-producing functions -- is there a way to test if a fn
    is generator-producing? (In the non-generator case, the fn is a 'tick' fn
    that I will call to produce results - a pre-generator implementation. )
    I can test for a generator itself with isinstance(f, types.Generator Type),
    but I'm interested in the fn that produces it. For example:

    if isGeneratorFn(f ):
    f = f()
    f.next() ...
    else:
    f()...

    If not, I guess it's fairly easy to specify a fn attr like so:
    def myGen(): yield foo
    myGen.isGenerat or = True

    but this is not as easy for instance methods, it seems. (No?)
    (BTW, +1 from me for PEPs with syntax that let you specify attrs for fn's
    and methods in-line with the def'n for cases like this, 'staticmethod', &c.
    No reason that c# should win on this one...)

    I would call f() the first time and see if the result is a generator object,
    but unfortunately in my case returning a generator is possible valid 'data'
    (to be scheduled later) and doesn't mean I should call .next() straight
    away.

    Ideas?
    thanks


  • Terry Reedy

    #2
    Re: generator testing and attrs


    "Mike" <vimakefile@yah oo.com> wrote in message
    news:gGfhb.5280 65$Oz4.405020@r wcrnsc54...[color=blue]
    > I need to be able to store a list of schedulable items, either[/color]
    regular[color=blue]
    > callables or generator-producing functions -- is there a way to test[/color]
    if a fn[color=blue]
    > is generator-producing?[/color]

    Yes, but I forget how. The ref-man section on type hierarchy lists
    and explains 'special attributes' for each type. Functions or code
    objects have an indication of normal vs. generator.

    TJR


    Comment

    • Miki Tebeka

      #3
      Re: generator testing and attrs

      Hello Mike,
      [color=blue]
      > I need to be able to store a list of schedulable items, either regular
      > callables or generator-producing functions -- is there a way to test if a fn
      > is generator-producing?[/color]
      if you do[color=blue][color=green][color=darkred]
      >>> def f(): return 1
      >>> dir(f)[/color][/color][/color]
      and[color=blue][color=green][color=darkred]
      >>> def f(): yield 1[/color][/color][/color]
      dir(g)
      You'll see that g has many attributes that f doesnt. Maybe you can use one of them.
      [color=blue]
      > if isGeneratorFn(f ):
      > f = f()
      > f.next() ...
      > else:
      > f()...
      >[/color]
      IMO a better way is letting the caller passing you ONLY functions.
      In case of a generator if should pass the .next of the generator.
      e.g.
      l = []
      def add_func(f):
      l.append(f)

      def add_gen(g):
      l.append(g().ne xt)

      for f in l:
      print f()

      HTH.
      Miki

      Comment

      • Mike

        #4
        Re: generator testing and attrs


        "Miki Tebeka" <mikit@zoran.co .il> wrote in message[color=blue]
        > You'll see that g has many attributes that f doesnt. Maybe you can use one[/color]
        of them.

        Hmm - doesn't seem so here:
        [color=blue][color=green][color=darkred]
        >>> def g(): yield None
        >>> dir(g)[/color][/color][/color]
        ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
        '__getattribute __', '__hash__', '__init__', '__module__', '__name__',
        '__new__', '__reduce__', '__reduce_ex__' , '__repr__', '__setattr__',
        '__str__', 'func_closure', 'func_code', 'func_defaults' , 'func_dict',
        'func_doc', 'func_globals', 'func_name'][color=blue][color=green][color=darkred]
        >>> def f(): return None
        >>> dir(f)[/color][/color][/color]
        ['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__',
        '__getattribute __', '__hash__', '__init__', '__module__', '__name__',
        '__new__', '__reduce__', '__reduce_ex__' , '__repr__', '__setattr__',
        '__str__', 'func_closure', 'func_code', 'func_defaults' , 'func_dict',
        'func_doc', 'func_globals', 'func_name'][color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]
        [color=blue]
        > IMO a better way is letting the caller passing you ONLY functions.
        > In case of a generator if should pass the .next of the generator.
        > ...code...[/color]

        As I said, I can't do that becuase I'm saving the items to be scheduled
        (evaluated lazily) -- I don't want to call f() or f.next() right right away.
        (The code sample could have included the comment "# much later..." between
        getting the funarg and calling it.)

        Ahh -- Looks like the original PEP (255) held the key:
        [color=blue][color=green][color=darkred]
        >>> hex(f.func_code .co_flags)[/color][/color][/color]
        '0x43'[color=blue][color=green][color=darkred]
        >>> hex(g.func_code .co_flags)[/color][/color][/color]
        '0x63'[color=blue][color=green][color=darkred]
        >>>[/color][/color][/color]

        ---
        mike


        Comment

        Working...