Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用functools partialmethod定义的函数的文档_Python - Fatal编程技术网

Python 使用functools partialmethod定义的函数的文档

Python 使用functools partialmethod定义的函数的文档,python,Python,我试图以某种方式获得一份文档,以使partialmethod发挥作用。我现在的代码是 from functools import partialmethod class Fun(object): def test(self, num): """ I have a documentation """ return num test2 = partialmethod(test, num=10) test2.__doc__ = """Blub"""

我试图以某种方式获得一份文档,以使partialmethod发挥作用。我现在的代码是

from functools import partialmethod

class Fun(object):

  def test(self, num):
    """
    I have a documentation
    """
    return num

  test2 = partialmethod(test, num=10)
  test2.__doc__ = """Blub"""

  test3 = partialmethod(test, num=20)
但如果我跑

a = Fun()
a.test2.__doc__ # only returns the partials documentation not "Blub"
Fun.test2.__doc__ # gives nothing
Sphinx使用
自动类
将它们列为
未记录成员


我读过,但这是否意味着无法将文档转换为partialmethod,或者我对此太愚蠢了?

不可能在
partialmethod
对象上设置docstring。这是因为
partialmethod
是一个用Python编写的类,类的实例从类的
\uuuuu doc\uuuuu
获取文档字符串,而不是从实例上的
\uuuuu doc\uuuuu
属性获取。函数的行为不同,函数对象的
\uuuuu doc\uuuu
属性被查看

根据使用
partialmethod
的复杂程度,您可以编写自己的版本来返回函数,而不是实例,从而允许您通过指定
\uuuu doc\uuu
属性来自定义文档

这里有一个简单的版本,我只做了一些基本的测试。我认为它适用于常见情况(例如,
func
是一个实际函数),但它可能不会像常规的
partialmethod
类型那样灵活,因此您应该仔细检查它是否完成了您需要它完成的所有操作:

import functools

def my_partialmethod(func, *args1, **kwargs1):
    @functools.wraps(func)  # copy attributes to start, they can be overwritten later
    def method(self, *args2, **kwargs2):
        return func(self, *args1, *args2, **kwargs1, **kwargs2)
    return method
调用
func
中的多重解包仅在Python 3.5中是合法的。在较旧的Python版本中,您必须自己将参数与以下内容合并:

    def method(self, *args2, **kwargs2):
        kwargs = kwargs1.copy()
        kwargs.update(kwargs2)
        return func(self, *(args1+args2), **kwargs)
下面是一个使用示例:

class Test(object):
    def method1(self, arg):
        "docstring1"
        print(arg)

    method2 = my_partial_method(method1, "foo")
    method2.__name__ = "method2"
    method2.__doc__ = "docstring2"

    method3 = my_partial_method(method1, arg="bar")
    method3.__name__ = "method3"
    method3.__doc__ = "docstring3"

当然,您可以选择覆盖哪些属性。我不确定使用
functools.wrapps是否是一个好主意,因为它可能会复制一堆无效的属性,超出我在示例中修改的属性。

在使用
functools.partialmethod
之前,我实际上有过这样一个装饰程序(好的,它有点不同)。但是这种方法有一些缺点,例如,它复制了原始函数签名(这通常是一件好事,但不适用于partials)。但partialmethod无法提供这样的功能,这似乎非常令人遗憾。特别是因为
partial
允许这样的用法-但仅用于函数而不是方法。不过,非常感谢你的回答,如果没有其他可能,我明天会接受你的回答。:-)是的,我的函数本质上是
部分的
,其中有一个特例是
self
。当包装普通方法时,它应该可以找到,但是如果包装像
staticmethod
或其他不希望获得
self
的描述符,它就不起作用。如果
wrapps
调用带来的麻烦多于好处,则可以删除它(包装函数的签名将是
(*args2,**kwargs2)
,这可能是一种改进,也可能不是一种改进)。