我如何以编程方式设置文档string?

我有一个包装函数返回一个函数。 有没有一种方法来编程设置返回的函数的文档string? 如果我可以写入__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自动创buildtesting用例。 我有一个包装函数,它创build一个类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 

如果我创build这个类,并尝试设置testSomething的文档string,我得到一个错误:

 >>> 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 

我将文档string传递到工厂函数,并使用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') 

一个instancemethod__func__获取它的文档string。 改变__func__的文档string。 (函数的__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__

只需使用装饰器。 这是你的情况:

 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' 

这里有一个类似的用例: Pythondynamic帮助和自动完成生成

__doc__仅在您的对象types为“type”时才能写入。

在你的情况下, add_three是一个函数,你可以将__doc__设置为任何string。

这是对typestype__doc__属性不能改变的补充。 有趣的是,只要类是使用types创build的,这就是真实的。 只要你使用一个元类,你实际上可以改变__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 ! """ 

我认为这应该是一个评论,但仍然收集我的第一个50分…

在你试图自动生成unittest.TestCase子类的情况下,你可能会有更多的里程覆盖它们的shortDescription方法。

这是将底层文档string剥离到第一行的方法,如在普通unit testing输出中所见; 重写它足以让我们控制像TeamCity这样的报表工具,这正是我们所需要的。