我如何以编程方式设置文档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这样的报表工具,这正是我们所需要的。