Self-identifying functions and macro-ish behavior

Discussion in 'Python' started by 63q2o4i02@sneakemail.com, Feb 15, 2006.

  1. Guest

    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
     
    , Feb 15, 2006
    #1
    1. Advertising

  2. Duncan Booth Guest

    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
     
    Duncan Booth, Feb 15, 2006
    #2
    1. Advertising

  3. Iain King Guest

    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
     
    Iain King, Feb 15, 2006
    #3
  4. 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
     
    Ben Cartwright, Feb 15, 2006
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ralf W. Grosse-Kunstleve
    Replies:
    16
    Views:
    595
    Lonnie Princehouse
    Jul 11, 2005
  2. Ralf W. Grosse-Kunstleve
    Replies:
    18
    Views:
    602
    Bengt Richter
    Jul 11, 2005
  3. Ralf W. Grosse-Kunstleve
    Replies:
    2
    Views:
    409
    Dan Sommers
    Jul 12, 2005
  4. falcon
    Replies:
    0
    Views:
    380
    falcon
    Jul 31, 2005
  5. Bart Kastermans
    Replies:
    6
    Views:
    409
    Bart Kastermans
    Jul 13, 2008
Loading...

Share This Page