Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Self-identifying functions and macro-ish behavior

Reply
Thread Tools

Self-identifying functions and macro-ish behavior

 
 
63q2o4i02@sneakemail.com
Guest
Posts: n/a
 
      02-15-2006
Hi, I was wondering how I may get a python function to know what its
name is without me having to write it manually? For example:

def func1():
<do some stuff1>
print 'func1'
return True

def func2():
<do some stuff2>
print 'func2'
return True

should be more like
def func1():
<do some stuff 1>
print <self-name>
return True

def func2():
<do some stuff 2>
print <self-name>
return True

I imagine this means things like closures which I'm not familiar with
(I'm not a CS person). In this case, each function is part of a class,
so I imagine I can take a dir() of the class if necessary.

This leads into my next related question, which is 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>?
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.)

Thanks for any help

Michael

 
Reply With Quote
 
 
 
 
Duncan Booth
Guest
Posts: n/a
 
      02-15-2006
Michael wrote:

> def func2():
> <do some stuff 2>
> print <self-name>
> return True
>
> I imagine this means things like closures which I'm not familiar with
> (I'm not a CS person). In this case, each function is part of a class,
> so I imagine I can take a dir() of the class if necessary.


Use the inspect module to find out what you need.

>
> This leads into my next related question, which is 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>?


By rolling it up neatly in a function?

>>> def printcaller():

print inspect.stack()[1][3]
return True

>>> def func1():

return printcaller()

>>> func1()

func1
True

But remember this prints the name under which the function was created, not
the name of the variable in which it is stored:

>>> func2 = func1
>>> func2()

func1

 
Reply With Quote
 
 
 
 
Iain King
Guest
Posts: n/a
 
      02-15-2006

http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> Hi, I was wondering how I may get a python function to know what its
> name is without me having to write it manually? For example:
>
> def func1():
> <do some stuff1>
> print 'func1'
> return True
>
> def func2():
> <do some stuff2>
> print 'func2'
> return True
>
> should be more like
> def func1():
> <do some stuff 1>
> print <self-name>
> return True
>
> def func2():
> <do some stuff 2>
> print <self-name>
> return True
>
> I imagine this means things like closures which I'm not familiar with
> (I'm not a CS person). In this case, each function is part of a class,
> so I imagine I can take a dir() of the class if necessary.


Yeah, I think these are closures (though when I learnt CS we didn't get
taught them). Try this:

def makeFunction(name):
def func():
<do stuff>
print name
return True
return func

func1 = makeFunction('func1')
func2 = makeFunction('func2')

>
> This leads into my next related question, which is 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>?


I think I've answered this too?

Iain

 
Reply With Quote
 
Ben Cartwright
Guest
Posts: n/a
 
      02-15-2006
(E-Mail Removed) 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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
os.path query functions behavior incorrect? Beman Dawes Python 4 04-06-2005 02:43 AM
Compiler behavior : Inlining external functions Raphael C Programming 5 01-11-2005 12:17 PM
please help me in distinguish redefining functions, overloading functions and overriding functions. Xiangliang Meng C++ 1 06-21-2004 03:11 AM
undefined behavior or not undefined behavior? That is the question Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM
Polymorphic behavior without virtual functions Dave C++ 9 12-26-2003 02:08 AM



Advertisments