The original request was to do it without using the function's
name, but you are depending on that name so your code is easy
enough to break. e.g. change the definition of f1 to:
def f2(func):
"this is f1"
s = func()
print s
return s
f1 = f2
del f2
Even Python-proper seems to get "confused" by this (though I
would contend it's correct behavior):
===================================
def f1():
raise Exception
f2 = f1
del(f1)
f2()
===================================
The traceback references f1() instead of f2. (other printing than
the calling line of code from the python file itself)
===================================
Traceback (most recent call last):
File "x.py", line 5, in ?
f2()
File "x.py", line 2, in f1
raise Exception
Exception
===================================
pdb suffers the same problem:
===================================
def f1():
import pdb; pdb.set_trace()
print 'hello'
f2 = f1
del(f1)
f2()
===================================
then, when run, use "where" to ask where Python thinks you are:
===================================
-> print 'hello'
(Pdb) where
c:\temp\z.py(7)?()
-> f2()
-> print 'hello'
===================================
It thinks we're in f1 as well even though f1 no longer exists.
My understanding was that the OP wanted a way to refrain from
hard-coding the function-name into the body of the function,
rather than to completely avoid the name of the function ever
being used anywhere.
Unless there's a mapping that I couldn't find (that would take
the current frame and map it to the calling
function/method/module object) the only way to completely avoid
this (AFAICT) would be to take the location information returned
by the stack frame, parse the file, and extract the doc-string
from the resulting line(s).
It gets hairier when the python is poorly written as one could
have pessimal cases of "valid" python docstrings that look like
def f(x): "docstring"; return x*2
or
def f(x):
"docstring"; return x*2
or common multiline items like
def f(x):
"""docstring1
docstring2"""
pass
or even worse,
def f(x):
"""this is a \"""docstring\"""
with \\\"""and\""" mutliple lines"""
pass
def f(x):
"this is\
a docstring"
pass
The parser also has to accomodate "raw" and "unicode" string
prefixes, as they're valid too:
def f(x):
r"raw!"
pass
def f(x):
u"Unicode"
pass
in addition. Okay...in most of these cases, the pathological
coder should be taken out back and beaten, but it's a non-trivial
problem
-tkc