首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >记录一流的指定函数

记录一流的指定函数
EN

Stack Overflow用户
提问于 2016-12-20 13:57:50
回答 2查看 157关注 0票数 1

我通过使用Python函数的第一类性质定义了一个函数,如下所示:

代码语言:javascript
复制
add_relative = np.frompyfunc(lambda a, b: (1 + a) * (1 + b) - 1, 2, 1)

要么我需要一种将docstring添加到定义为它的函数的方法,要么使用更常见的格式实现相同的功能,这样我就可以以正常的方式编写docstring:

代码语言:javascript
复制
def add_relative(a, b):
    """
    Docstring
    """
    return np.frompyfunc(lambda a, b: (1 + a) * (1 + b) - 1, 2, 1)(a, b)

,当函数被调用时,它可以工作,如

代码语言:javascript
复制
 add_relative(arr1, arr2)

但是我就失去了调用方法的能力,例如

代码语言:javascript
复制
add_relative.accumulate(foo_arr, dtype=np.object)

我猜这是因为函数在使用frompyfunc时变得更像一个类,它是从ufunc派生的。

我想我可能需要定义一个类,而不是函数,但我不确定如何定义。我可以接受这一点,因为这样我就可以像平常一样轻松地添加一个docstring。

我标记这个coding-style是因为原来的方法有效,但是很难被很容易地记录下来,很抱歉,如果标题不清楚,我不知道正确的词汇表来描述这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-20 15:22:33

更新1:关闭,但仍然不够好。因为修饰函数的__doc__属性不能更新,而且由于Sphinx仍然只获取修饰函数的docstring,这并不能解决我的问题。

更新2: --我在下面提出的解决方案--对于源代码中的文档来说很好。对于狮身人面像的文档,我只需用

代码语言:javascript
复制
.. function:: sum_relative(a, b)

   <Docstring written in rst format>

它很难看,很麻烦,而且是手动的,但这意味着我在源代码中有我的好文档,在狮身人面像( Sphinx )中有好的文档。

所有这些问题都源于一个事实,即__doc__属性的numpy.ufunc是不可变的。如果有人知道原因,我很想听听为什么。我猜是因为它来自用C编写的东西,而不是纯Python。不管怎样,这很烦人。

我发现我可以使用一个装饰器来应用np.frompyfunc()来解决这个问题。

我编写基本函数(在原始示例中为lambda ),并按常规方式添加一个docstring,然后应用装饰器:

代码语言:javascript
复制
def as_ufunc(func):
    return np.frompyfunc(func, 2, 1)

@as_ufunc
def sum_relative(a, b):
    """
    Docstring
    """
    return (1 + a) * (1 + b) - 1

这不是一个完美的解决方案,原因如下:

  • sum_relative.__doc__frompyfunc覆盖到一个通用和无用的docstring中。我在这里并不介意,因为我真的很关心使用Sphinx从docstring生成的文档,而不是通过编程访问它。您可能会认为尝试类似functools.wrapsfunctools.update_wrapper之类的东西,但是numpy.ufunc__doc__成员显然是不可变的。
  • 我必须对frompyfunc的第二个参数进行硬编码。我在这里并不介意,因为我在这里使用的所有案例都需要相同的值。
  • 编辑:有可能绕开上面的观点,它有点冗长,但不多: def as_ufunc(nin,nout):def _decorator(func):返回np.frompyfunc(func,nin,nout)返回_decorator @as_ufunc(2,1) def sum_relative(a,b):“”Docstring“”返回(1 + a) * (1 + b) -1
  • 它比原来的解决方案更冗长。我不介意,因为我现在有了docstring。
票数 2
EN

Stack Overflow用户

发布于 2020-04-28 17:23:03

我想像这样的事情可能会奏效:

代码语言:javascript
复制
UFUNC_ATTRS = (
    'nin',
    'accumulate',
    # etc...
)


def redirectattribtues(destination):
    def decorator(func):
        for attribute in UFUNC_ATTRS:
            setattr(func, attribute, getattr(destination, attribute))
        return func
    return decorator


ufunc = np.frompyfunc(lambda a, b: (1 + a) * (1 + b) - 1, 2, 1)


@redirectattribtues(destination=ufunc)
def add_relative(a, b):
    """
    Docstring
    """
    return ufunc(a, b)


# test
arr1 = np.array(list(range(0, 10)))
arr2 = np.array(list(range(10, 20)))
print(add_relative(arr1, arr2))
print(add_relative.accumulate(arr1, dtype=object))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41244063

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档