如何以编程方式设置文档字符串?

问题描述 投票:0回答:7

我有一个返回函数的包装函数。有没有办法以编程方式设置返回函数的文档字符串?如果我可以写信给

__doc__
,我会做以下事情:

def wrapper(a):
    def add_something(b):
       return a + b
    add_something.__doc__ = 'Adds ' + str(a) + ' to `b`'
    return add_something

那我就可以了

>>> add_three = wrapper(3)
>>> add_three.__doc__
'Adds 3 to `b`

但是,由于

__doc__
是只读的,所以我不能这样做。正确的做法是什么?


编辑:好的,我想保持简单,但这当然不是我真正想做的。尽管一般来说

__doc__
在我的情况下是可写的,但它不是。

我正在尝试自动为

unittest
创建测试用例。我有一个包装函数,它创建一个类对象,该对象是
unittest.TestCase
:

的子类
import unittest
def makeTestCase(filename, my_func):
    class ATest(unittest.TestCase):
        def testSomething(self):
            # Running test in here with data in filename and function my_func
            data  = loadmat(filename)
            result = my_func(data)
            self.assertTrue(result > 0)

    return ATest

如果我创建此类并尝试设置

testSomething
的文档字符串,我会收到错误:

>>> def my_func(): pass
>>> MyTest = makeTestCase('some_filename', my_func)
>>> MyTest.testSomething.__doc__ = 'This should be my docstring'
AttributeError: attribute '__doc__' of 'instancemethod' objects is not writable
python docstring
7个回答
61
投票

instancemethod
从其
__func__
获取其文档字符串。改为更改
__func__
的文档字符串。 (函数的
__doc__
属性是可写的。)

>>> class Foo(object):
...     def bar(self):
...         pass
...
>>> Foo.bar.__func__.__doc__ = "A super docstring"
>>> help(Foo.bar)
Help on method bar in module __main__:

bar(self) unbound __main__.Foo method
    A super docstring

>>> foo = Foo()
>>> help(foo.bar)
Help on method bar in module __main__:

bar(self) method of __main__.Foo instance
    A super docstring

来自 2.7 文档

用户自定义方法

用户定义的方法对象组合了类、类实例(或 None)和任何可调用的方法 对象(通常是用户定义的函数)。

特殊只读属性:im_self是类实例对象,im_func是函数 目的; im_class 是绑定方法的 im_self 的类或要求绑定方法的类 未绑定方法的方法;

__doc__
是方法的文档(与
im_func.__doc__
);
__name__
是方法名称(与
im_func.__name__
相同);
__module__
是定义该方法的模块的名称,如果不可用则为 None。

2.2 版本更改:im_self 用于引用定义该方法的类。

2.6 版中的更改:为了向前兼容 3.0,im_func 也可用作

__func__
和 im_self 为
__self__


24
投票

我会将文档字符串传递到工厂函数中,并使用

type
手动构造该类。

def make_testcase(filename, myfunc, docstring):
    def test_something(self):
        data = loadmat(filename)
        result = myfunc(data)
        self.assertTrue(result > 0)

    clsdict = {'test_something': test_something,
               '__doc__': docstring}
    return type('ATest', (unittest.TestCase,), clsdict)

MyTest = makeTestCase('some_filename', my_func, 'This is a docstring')

12
投票

只使用装饰器。这是您的案例:

def add_doc(value):
    def _doc(func):
        func.__doc__ = value
        return func
    return _doc

import unittest
def makeTestCase(filename, my_func):
    class ATest(unittest.TestCase):
        @add_doc('This should be my docstring')
        def testSomething(self):
            # Running test in here with data in filename and function my_func
            data  = loadmat(filename)
            result = my_func(data)
            self.assertTrue(result > 0)

    return ATest

def my_func(): pass

MyTest = makeTestCase('some_filename', my_func)
print MyTest.testSomething.__doc__
> 'This should be my docstring'

这是一个类似的用例:Python 动态帮助和自动完成生成


11
投票

这是对

__doc__
类型的类的
type
属性无法更改这一事实的补充。有趣的是,只有当类是使用类型创建的时候,这才是正确的。一旦你使用了元类,你实际上就可以改变
__doc__

该示例使用 abc (AbstractBaseClass) 模块。它使用特殊的

ABCMeta
元类

来工作
import abc

class MyNewClass(object):
    __metaclass__ = abc.ABCMeta

MyClass.__doc__ = "Changing the docstring works !"

help(MyNewClass)

将会导致

"""
Help on class MyNewClass in module __main__:

class MyNewClass(__builtin__.object)
 |  Changing the docstring works !
"""

5
投票

__doc__
仅当您的对象类型为“type”时才不可写。

在您的情况下,

add_three
是一个函数,您可以将
__doc__
设置为任何字符串。


0
投票

在您尝试自动生成 unittest.TestCase 子类的情况下,您可能会覆盖其 shortDescription 方法。

这是将底层文档字符串剥离到第一行的方法,如正常单元测试输出中所示;覆盖它足以让我们控制 TeamCity 等报告工具中显示的内容,这正是我们所需要的。


0
投票

是的,您可以通过直接将字符串分配给函数对象的

__doc__
属性来以编程方式设置函数的文档字符串。 这是如何在包装函数中实现此目的的示例:

def wrapper_function():
    def inner_function():
        pass
    
    # Set the docstring for the inner function
    inner_function.__doc__ = "This is the docstring for the inner function."
    
    return inner_function

# Create the wrapped function
wrapped_function = wrapper_function()

# Access and print the docstring of the wrapped function
print(wrapped_function.__doc__)

在此示例中,

wrapper_function
返回
inner_function
,并且在
wrapper_function
内,通过将字符串分配给
inner_function
属性以编程方式设置
__doc__
的文档字符串。

记得在返回函数之前设置文档字符串,因为函数返回后修改属性不会影响返回函数的文档字符串。

© www.soinside.com 2019 - 2024. All rights reserved.