我想提取一個函式的檔案字串,一旦它被包裝在lambda.
考慮以下示例:
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__)
我得到:
a 1 Foo docstring
b 2 None
如何參考在“呼叫”函式時呼叫的函式lambda?
更新
感謝所有回答:
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
uj5u.com熱心網友回復:
沒有“好”的方法可以做到這一點。但是,使用該inspect模塊在技??術上是可行的。這是一個非常脆弱和脆弱的實作,適合您獲取 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
正如我所說,這個實作是脆弱的。例如,如果呼叫的第一個函式不在globals. 但是,如果您發現自己陷入非常可怕的困境,您可能可以為您的用例組合一個解決方案。
但是,如果可能的話,您應該改用 functools
import functools
def foo(a=1):
"""Foo docstring"""
return a
b = functools.partial(foo, 2)
print(b.func.__doc__)
uj5u.com熱心網友回復:
好吧,嘗試將諸如檔案之類的功能添加到 smt 中,根據定義,這些功能應該是“匿名的”……只能以一種棘手的方式來完成。我可以使用嵌套裝飾器來實作這一點。
首先要注意的print('__doc__' in dir(lambda: ''))是True。
def add_doc_to_lambda(func, a, docs=''):
# also provide custom docs parameter
if docs == '':
return (lambda l: (lambda _=setattr(l, '__doc__', func.__doc__): l)())(lambda: func(a))
return (lambda l: (lambda _=setattr(l, '__doc__', docs): l)())(lambda: func(a))
def foo(a=1):
"""Foo docstring"""
return a
dct = {
"a": foo,
"b": add_doc_to_lambda(foo, 2), # add_doc_to_lambda(foo, 2, 'lambda docs') # case of custom docs
}
for k, v in dct.items():
print('>>> ', k, v(), v.__doc__)
輸出
>>> a 1 Foo docstring
>>> b 2 Foo docstring # lambda docs # case custom docs
備注:
add_doc_to_lambda可呼叫
print(dct['b'])
<function dec.<locals>.<lambda> at 0x7f6eda92ee50>
- 還有一種更直接的方式,例如
l = lambda: foo(2)
l.__doc__ = foo.__doc__
print(l.__doc__)
有效,但將 lambda 函式分配給變數是一種不好的做法。
uj5u.com熱心網友回復:
我建議您lambda在這里使用不同的機制。任何回傳正確包裝的東西FunctionType都可以直接訪問正確的__doc__. 一種常見的方法是使用functools.partialwith functools.wraps:
from functools import partial, wraps
dct = {
"a": foo,
"b": wraps(foo)(partial(foo, 2)),
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/326723.html
