对于与“表现良好”的装饰器一起工作的硬编码版本。它必须在函数之后声明。如果函数稍后反弹,则会在此处更新更改。
def get_name_doc():
# global function # this is optional but makes your intent a bit more clear.
return function.__name__, function.__doc__
这是一个相当讨厌的 hack,因为它滥用了默认 args 的工作方式。它将使用在此函数“初始化”时绑定到的任何函数,并且即使该函数被反弹,也要记住它。用 args 调用它会导致有趣的结果。
def get_name_doc(fn=function):
return fn.__name__, fn.__doc__
还有一个动态的,它仍然是硬编码的,但在函数被调用时会更新,参数为 True。基本上这个版本只会在被告知这样做时更新。
def get_name_doc(update=False):
global fn
if update:
fn = function
return fn.__name__, fn.__doc__
现在当然也有装饰器的例子。
@decorator # applying the decorator decorator to make it well behaved
def print_name_doc(fn, *args, **kwargs):
def inner(*args, **kwargs):
print(fn.__doc__, fn.__name__) # im assuming you just want to print in this case
return fn(*args, **kwargs)
return inner
你应该阅读装饰器装饰器(至少)。查看 NamedTuple 源(来自集合模块),因为它涉及到硬编码。可悲的是,命名元组代码相当奇怪。它是一种与 eval 而非传统代码一起使用的字符串格式,但它工作得非常巧妙。这似乎是最有希望的变体。您也可以使用元类来做到这一点,这会导致代码简洁,但隐藏在幕后的讨厌的东西,您需要编码。这个 id 建议不要
我怀疑可能有一种比进入检查/反射/模板/元类更简单的方法,只需在模块末尾添加以下行。
help(<module>)
您正在处理的模块的名称在哪里(字符串)。甚至是变量 __name__。如果使用多个模块或单个类,我认为这也可以在 __init__.py 文件中完成。