Accessing func_name from inside a function

Eyal Lotem eyal.lotem at gmail.com
Sun Mar 26 16:23:10 EST 2006


Steven D'Aprano wrote:

> 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))

Another possibility would be:

def recursive_func(func):
    def new_func(*args, **kw):
        return func(new_func, *args, **kw)
    return new_func

@recursive_func
def Ackermann(recurse, i, j):
    # yadda yadda
    recurse(i-1, ...), recurse(y-2, ...)

> 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.

By the way, the "real" problem here is referencing by name, rather than
using "true" references. Which is the result of using a textual language.
The "real" solution would be to store real-references to the function and
only present the name in a graphical interface.



More information about the Python-list mailing list