简体   繁体   English

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

[英]How do I programmatically set the docstring?

I have a wrapper function that returns a function.我有一个返回函数的包装函数。 Is there a way to programmatically set the docstring of the returned function?有没有办法以编程方式设置返回函数的文档字符串? If I could write to __doc__ I'd do the following:如果我可以写信给__doc__我会执行以下操作:

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

Then I could do然后我可以做

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

However, since __doc__ is read-only, I can't do that.但是,由于__doc__是只读的,我不能这样做。 What's the correct way?正确的方法是什么?


Edit: Ok, I wanted to keep this simple, but of course this is not what I'm actually trying to do.编辑:好的,我想保持这个简单,但当然这不是我真正想要做的。 Even though in general __doc__ is writeable in my case it isn't.尽管通常__doc__在我的情况下是可写的,但它不是。

I am trying to create testcases for unittest automatically.我正在尝试自动为unittest创建测试用例。 I have a wrapper function that creates a class object that is a subclass of unittest.TestCase :我有一个包装函数,它创建一个类对象,它是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

If I create this class and try to set the docstring of testSomething I get an error:如果我创建这个类并尝试设置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

An instancemethod gets its docstring from its __func__ .一个instancemethod从它的__func__获取它的文档字符串。 Change the docstring of __func__ instead.改为更改__func__的文档字符串。 (The __doc__ attribute of functions are writeable.) (函数的__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

From the 2.7 docs :2.7 文档

User-defined methods用户定义的方法

A user-defined method object combines a class, a class instance (or None) and any callable object (normally a user-defined function).用户定义的方法对象组合了一个类、一个类实例(或 None)和任何可调用对象(通常是一个用户定义的函数)。

Special read-only attributes: im_self is the class instance object, im_func is the function object;特殊的只读属性:im_self 是类实例对象,im_func 是函数对象; im_class is the class of im_self for bound methods or the class that asked for the method for unbound methods; im_class 是绑定方法的 im_self 类或未绑定方法请求方法的类; __doc__ is the method's documentation (same as im_func.__doc__ ); __doc__是方法的文档(与im_func.__doc__相同); __name__ is the method name (same as im_func.__name__ ); __name__是方法名称(与im_func.__name__相同); __module__ is the name of the module the method was defined in, or None if unavailable. __module__是定义方法的模块的名称,如果不可用则为 None 。

Changed in version 2.2: im_self used to refer to the class that defined the method.在 2.2 版更改: im_self 用于引用定义方法的类。

Changed in version 2.6: For 3.0 forward-compatibility, im_func is also available as __func__ , and im_self as __self__ .在 2.6 版更改:对于 3.0 向前兼容性, im_func 也可用作__func__ im_self 可用作__self__

I would pass the docstring into the factory function and use type to manually construct the class.我会将文档字符串传递给工厂函数并使用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')

This is an addition to the fact that the __doc__ attribute of classes of type type cannot be changed.这是对 type type的类的__doc__属性无法更改这一事实的补充。 The interesting point is that this is only true as long as the class is created using type.有趣的一点是,这仅在类是使用类型创建的情况下才成立。 As soon as you use a metaclass you can actually just change __doc__ .只要您使用元类,您实际上就可以更改__doc__

The example uses the abc (AbstractBaseClass) module.该示例使用 abc (AbstractBaseClass) 模块。 It works using a special ABCMeta metaclass它使用特殊的ABCMeta元类工作

import abc

class MyNewClass(object):
    __metaclass__ = abc.ABCMeta

MyClass.__doc__ = "Changing the docstring works !"

help(MyNewClass)

will result in会导致

"""
Help on class MyNewClass in module __main__:

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

Just use decorators.只需使用装饰器。 Here's your case:这是你的情况:

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'

Here's a similar use case: Python dynamic help and autocomplete generation这是一个类似的用例: Python dynamic help and autocomplete generation

__doc__ is not writable only when your object is of type 'type'. __doc__仅当您的对象属于“类型”类型时才可写。

In your case, add_three is a function and you can just set __doc__ to any string.在您的情况下, add_three是一个函数,您可以将__doc__设置为任何字符串。

In the case where you're trying to automatically generate unittest.TestCase subclasses, you may have more mileage overriding their shortDescription method.在您尝试自动生成 unittest.TestCase 子类的情况下,您可能有更多的里程覆盖他们的shortDescription方法。

This is the method that strips the underlying docstring down to the first line, as seen in normal unittest output;这是将底层文档字符串剥离到第一行的方法,如正常的单元测试输出所示; overriding it was enough to give us control over what showed up in reporting tools like TeamCity, which was what we needed.覆盖它足以让我们控制在 TeamCity 等报告工具中显示的内容,这正是我们所需要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM