更新 1:
終了しますが、これではまだ十分ではありません。装飾された関数の__doc__
属性は更新できず、Sphinx はまだ装飾された関数の docstring しか取得しないため、これで問題は解決しません。
更新 2:
以下で提案するソリューションは、ソース コード内のドキュメントに適しています。Sphinx のドキュメントについては、ドキュメント文字列を次のように上書きするだけで済みました。
.. function:: sum_relative(a, b)
<Docstring written in rst format>
醜く、ハックで、手動ですが、ソース コードに優れたドキュメントがあり、Sphinx に優れたドキュメントがあることを意味します。
All of the issues stem from the fact that the __doc__
attribute of a numpy.ufunc
is immutable. If anyone knows why, I'd love to hear why. I'm guessing something related to the fact that it comes from something written in C, not pure Python. Regardless, it's very annoying.
I found that I could solve the issue using a decorator to apply np.frompyfunc()
.
I write the base function (the lambda in the original example) and add a docstring as normal and then apply the decorator:
def as_ufunc(func):
return np.frompyfunc(func, 2, 1)
@as_ufunc
def sum_relative(a, b):
"""
Docstring
"""
return (1 + a) * (1 + b) - 1
It's not a perfect solution for the following reasons:
sum_relative.__doc__
is overwritten by frompyfunc
to a generic and unhelpful docstring. I don't mind here because I really care about the docs generated with Sphinx from the docstring, and not accessing it programatically. You might think to try something like functools.wraps
or functools.update_wrapper
, however the __doc__
member of a numpy.ufunc
is apparenly immutable.
I have to hardcode the second two arguments for frompyfunc
. I don't mind here because all the cases that I use it here will require the same values.
Edit: It is possible to get around the above point, it's a little more verbose, but not much:
def as_ufunc(nin, nout):
def _decorator(func):
return np.frompyfunc(func, nin, nout)
return _decorator
@as_ufunc(2, 1)
def sum_relative(a, b):
"""
Docstring
"""
return (1 + a) * (1 + b) - 1
- It's more verbose than the original solution. I don't mind because I now have the docstring.