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?
Update
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
Advertisement
Answer
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__)