I would like to extract the docstring of a function once it has been wrapped in lambda
.
Consider the following example:
def foo(a=1):
"""Foo docstring"""
return a
dct = {
"a": foo,
"b": lambda: foo(2),
}
for k, v in dct.items()
print(k, v(), v.__doc__)
I get:
a 1 Foo docstring
b 2 None
How can I reference the function called on "calling" the lambda
one?
Thanks for all answers:
from functools import partial
def foo(a=1):
"""Foo docstring"""
return a
dct = {
"a": foo,
"b": partial(foo, 2),
}
for k, v in dct.items():
if hasattr(v, "func"):
print(k, v(), v.func.__doc__)
else:
print(k, v(), v.__doc__)
a 1 Foo docstring
b 2 Foo docstring
There is no "good" way to do this. However, it is technically possible using the inspect
module. Here is a very brittle and fragile implementation that fits your use case of getting the docstring of the first function called by a lambda:
import inspect
import re
def get_docstring_from_first_called_function(func):
# the inspect module can get the source code
func_source = inspect.getsource(func)
# very silly regex that gets the name of the first function
name_of_first_called_function = re.findall(r'\w+|\W+', func_source.split("(")[0])[-1]
# if the function is defined at the top level, it will be in `globals()`
first_called_function = globals()[name_of_first_called_function]
return first_called_function.__doc__
def foo(a=1):
"""Foo docstring"""
return a
b = lambda: foo(2)
print(get_docstring_from_first_called_function(b))
> Foo docstring
As I said, this implementation is fragile and brittle. For instance, it breaks instantly if the first function called is not in globals
. But if you find yourself in very dire straits, you can probably hack together a solution for your use case.
If at all possible, however, you should use functools instead
import functools
def foo(a=1):
"""Foo docstring"""
return a
b = functools.partial(foo, 2)
print(b.func.__doc__)