Accessing func_name from inside a function

Steven D'Aprano steve at REMOVETHIScyber.com.au
Sat Mar 25 20:59:23 EST 2006


On Sun, 26 Mar 2006 10:19:36 +1000, Ben Finney wrote:

> "James Thiele" <jamesthiele.usenet at gmail.com> writes:
> 
>> I'd like to access the name of a function from inside the function.
> 
> A function, like most other objects in Python, can have any number of
> names bound to it without the object being informed. Any of those
> names can then be used to reference the object, and the object has no
> way of knowing by what name it was referenced.
> 
> Because of this fallacy, 

"You keep using that word. I do not think it means what you think it
means." 

*wink*

> it's generally considered bad programming
> style to want to know "the" name of the current object from inside
> that object.

I agree whole-heartedly with Ben's sentiments here, although I can also
point out by example why it might be useful for a function to know it's
own name:

def Ackermann(i, j):
    """Returns the Ackermann function of integers i and j.

    The Ackermann function is an example of a function which grows at a
    much faster than exponential rate. Ackermann(i, j) for i > 2 grows
    even more quickly than 2**2**2**...**2 (where there are j exponents).
    It is an example of a recursive function which is not primitively
    recursive and was discovered by the German mathematician Wilhelm
    Ackermann in 1928.

    >>> Ackermann(1, 1)
    2
    >>> Ackermann(2, 2)
    16
    >>> Ackermann(2, 3)
    65536

    The Ackermann function is not defined for i,j <= 0.

    See http://en.wikipedia.org/wiki/Ackermann_function
    and 'Introduction to Algorithms' by Thomas H Cormen, Charles E
    Leiserson, Ronald L Rivest, pp. 451-453.
    """
    if i < 0 or j < 0:
        raise ValueError(
        "arguments to the Ackermann function must be positive")
    if i == 1:
        return 2**j
    if j == 1:
        return Ackermann(i-1, 2)
    return Ackermann(i-1, Ackermann(i, j-1))

Notice that if you change the name of the function, you have to change it
in no less than three places in the function definition and four places
in the __doc__ string, but a global search and replace is too greedy and
will change too much. As a general principle, it is considered best
practice to code in such a way that if you change something, you only need
to change it in one place.

I guess that the Original Poster wants some magic that allows functions to
do this:

def Ackermann(i, j):
    """Returns the Ackermann function of integers i and j.

    The Ackermann function is an example of a function which grows at a
    much faster than exponential rate. %MAGIC(i, j) for i > 2 grows
    even more quickly than 2**2**2**...**2 (where there are j exponents).
    It is an example of a recursive function which is not primitively
    recursive and was discovered by the German mathematician Wilhelm
    Ackermann in 1928.

    >>> %MAGIC(1, 1)
    2
    >>> %MAGIC(2, 2)
    16
    >>> %MAGIC(2, 3)
    65536

    The Ackermann function is not defined for i,j <= 0.

    See http://en.wikipedia.org/wiki/Ackermann_function
    and 'Introduction to Algorithms' by Thomas H Cormen, Charles E
    Leiserson, Ronald L Rivest, pp. 451-453.
    """
    if i < 0 or j < 0:
        raise ValueError(
        "arguments to the Ackermann function must be positive")
    if i == 1:
        return 2**j
    if j == 1:
        return %MAGIC(i-1, 2)
    return %MAGIC(i-1, %MAGIC(i, j-1))


Now he can easily rename "Ackermann" to "Ack" and need only make the
change in one place.

I suspect that the correct solution to the O.P.'s problem is to think
carefully about the names of your functions in advance.



-- 
Steven.




More information about the Python-list mailing list