any macro-like construct/technique/trick?

Andrew Dalke dalke at dalkescientific.com
Thu Jun 2 05:22:11 CEST 2005


Mac wrote:
> After I wrote my post I realized I didn't provide enough context of
> what I'm doing, [explanation followed]

I have a similar case in mind.  Some graph algorithms work with a
handler, which is notified about various possible events: "entered
new node", "doing a backtrack", "about to leave a node".  A general
algorithm may implement many of these.  But if the handler doesn't
care about some of the events there's still the cost of either
doing a no-op call or checking if the callback function doesn't exist.

I've considered the idea of limited macro/template support for that
case, which either removes a callback or perhaps in-lines some
user-supplied code for the given circumstance.


>it... no... wait... no good, the problem is the following case:
>    # real line of code
>    DbgObjFoo(a,b,costly_function(c))
>    # real line of code

In another branch I suggested

  debug_emit(DbgObjFoo, a, b, costly_function(c))

which obviously wouldn't work for this case.  The following lightly
tested code would work (assuming appropriate debugging)

  debug_emit(DbgObjFoo, a, b, 
     Call(costly_function, c, Call(expensive_function, d)))

def debug_emit(klass, *args):
  if debug:
     emit_dbg_code(Call(klass, *args)())

class Call:
  def __init__(self, f, *args):
    self.f = f
    self.args = args
  def __call__(self):
    args = []
    for arg in self.args:
      if isinstance(arg, Call):
        args.append(arg())
      else:
        args.append(arg)
    return self.f(*args)

There's still the overhead of making the Call objects, but it
shouldn't be that large.  You can save a smidgeon by doing

if debug:
  class Call:
    ... as defined earlier
else:
  def Call(f, *args): pass



				Andrew
				dalke at dalkescientific.com




More information about the Python-list mailing list