Self-identifying functions and macro-ish behavior
Ben Cartwright
bencvt at gmail.com
Wed Feb 15 10:51:14 EST 2006
63q2o4i02 at sneakemail.com wrote:
> How do I get some
> sort of macro behavior so I don't have to write the same thing over and
> over again, but which is also not neatly rolled up into a function,
> such as combining the return statements with a printing of <self-name>?
Decorators: http://www.python.org/peps/pep-0318.html
> My application has a bunch of functions that must do different things,
> then print out their names, and then each call another function before
> returning. I'd like to have the last function call and the return in
> one statement, because if I forget to manually type it in, things get
> messed up.
>
> (ok, I'm writing a parser and I keep track of the call level with a tab
> count, which gets printed before any text messages. So each text
> message has a tab count in accordance with how far down the parser is.
> Each time a grammar rule is entered or returned from, the tab count
> goes up or down. If I mess up and forget to call tabsup() or tabsdn(),
> the printing gets messed up. There are a lot of simple cheesy
> production rules, [I'm doing this largely as an exercise for myself,
> which is why I'm doing this parsing manually], so it's error-prone and
> tedious to type tabsup() each time I enter a function, and tabsdn()
> each time I return from a function, which may be from several different
> flow branches.)
def track(func):
"""Decorator to track calls to a set of functions"""
def wrapper(*args, **kwargs):
print " "*track.depth + func.__name__, args, kwargs or ""
track.depth += 1
result = func(*args, **kwargs)
track.depth -= 1
return result
return wrapper
track.depth = 0
# Then to apply the decorator to a function, e.g.:
def f(x):
return True
# Add this line somewhere after the function definition:
f = track(f)
# Alternately, if you're using Python 2.4 or newer, just define f as:
@track
def f(x):
return True
# Test it:
@track
def fact(n):
"""Factorial of n, n! = n*(n-1)*(n-2)*...*3*2"""
assert n >= 0
if n < 2:
return 1
return n * fact(n-1)
@track
def comb(n, r):
"""Choose r items from n w/out repetition, n!/(r!*(n-r)!)"""
assert n >= r
return fact(n) / fact(r) / fact(n-r)
print comb(5, 3)
# Output:
"""
comb (5, 3)
fact (5,)
fact (4,)
fact (3,)
fact (2,)
fact (1,)
fact (3,)
fact (2,)
fact (1,)
fact (2,)
fact (1,)
10
"""
--Ben
More information about the Python-list
mailing list