如何使用 overload/dispatch 装饰器记录 Python 函数?

How to document Python functions with overload/dispatch decorators?

将文档应用于多分派函数

我正在使用 multipledispatch 包,其方式类似于下面的示例代码。当我在 Python 命令行中请求 help(my_add) 时,我希望能够看到 docstring 文本,但我看到的只是关于装饰器的信息。

Functools.wraps一定是方法,但是怎么做呢?

我已经查过了functools.wraps, which I'm sure is what I want to use. I have found examples of how to use it, such as this and this

但是有两个问题我还是不太明白:

  1. 如何将 functools.wraps 应用于我不使用的外部装饰器 "own"。
  2. 如何将它专门应用于具有多个分派的这种情况,因为我要包装的函数将有多个 docstrings 与相同的函数名称相关联。

示例:修饰函数创建

下面举例说明。

>>> from multipledispatch import dispatch
>>> @dispatch(str, str)
... def my_add(elem1, elem2):
...   '''A flavor of 'add' where two strings are concatenated.'''
...   return elem1 + ' ' + elem2
... 
>>> @dispatch(int, int)
... def my_add(elem1, elem2):
...   '''A flavor of 'my_add' where two strings are concatenated.'''
...   return elem1 + elem2
... 
>>> my_add('hey','you')
'hey you'
>>> my_add(4, 5)
9
>>> my_add(4.5, 6)

(追溯细节已删除...)

KeyError: (<class 'float'>, <class 'int'>)
During handling of the above exception, another exception occurred:
NotImplementedError: Could not find signature for my_add: <float, int>

我想显示该错误和不同的调度只是为了表明该部分正在按我想要的方式工作(寻找匹配的调度并调用函数的关联 "flavor")。

示例:在装饰函数上调用 help 失败!

但是接下来,如果我尝试查看帮助,而不是看到我提供的简单 docstring,我会看到与 @dispatch 装饰器关联的文档字符串。

>>> help(my_add)

Help on Dispatcher in module multipledispatch.dispatcher object:

my_add = class Dispatcher(builtins.object)
 |  Methods defined here:
 |  
 |  __call__(self, *args, **kwargs)
 |      Call self as a function.
 |  
 |  __getstate__(self)
 |  

等等


我什至不确定它应该显示什么,因为有可能有 2 个冲突的文档字符串 我想向前推进。所以,我试着看看我是否可以在实际上是 运行 的函数上调用帮助,但当然它会为我提供有关返回数据类型的帮助。例如,

>>> help(my_add(3, 5))

Help on int object:

class int(object)
 |  int(x=0) -> integer
 |  int(x, base=10) -> integer
 |  
 |  Convert a number or string to an integer, or return 0 if no arguments

functools.wraps() 装饰器必须是 装饰器实现的一部分,您不能事后应用它。这里的问题是装饰器 returns 自定义 class 的实例,而 help() 只能显示 class 的文档那个例子。

装饰器returnsDispatcher()实例已经有一个__doc__属性,其中列出了所有装饰函数的文档字符串。根据您链接的文档:

The Dispatcher creates a detailed docstring automatically. To add a description of the multimethod itself, provide it when creating the Dispatcher.

您的示例也有文档字符串:

>>> print(my_add.__doc__)
Multiply dispatched method: my_add

Inputs: <str, str>
-------------------
A flavor of 'add' where two strings are concatenated.

Inputs: <int, int>
-------------------
A flavor of 'my_add' where two strings are concatenated.

(请注意,您的示例正确反映了文档字符串,但有错误)。

这里真正的问题是 help() 只能打印 class__doc__ 字符串,所以 print(type(my_add).__doc__))用作起点。这不是可以轻易改变的事情;坚持直接打印实例的 __doc__ 属性。