Вопрос

У меня есть функция обертки, которая возвращает функцию. Есть ли способ программно установить Docstring возвращенной функции? Если бы я мог написать __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

Если я создаю этот класс и попытаюсь установить DOCSTRING 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
Это было полезно?

Решение

Я бы передал DOCSTRING в заводскую функцию и использовать 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__. Отказ Изменить DOCSTRING __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_SE - это объект экземпляра класса, IM_FUNC - это объект функции; im_class - это класс im_self для связанных методов или класса, который попросил метод несвязанных методов; __doc__ это документация метода (такая же, как im_func.__doc__); __name__ это имя метода (так же, как im_func.__name__); __module__ Имя модуля метод был определен или нет, если он недоступен.

Изменено в версии 2.2: im_self используется для ссылки на класс, который определил метод.

Изменено в версии 2.6: для 3.0 Forver-совместимости, 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'

Вот аналогичный случай использования: Python Dynamic Help и автозаполнение поколения

Это дополнение к тому, что __doc__ Атрибут классов типа type не может быть изменен. Интересный момент заключается в том, что это верно только до тех пор, пока класс создан с использованием типа. Как только вы используете метакласс, вы действительно можете просто изменить __doc__.

Пример использует модуль ABC (абстрактныйBASECLASS). Это работает с использованием специального 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 очков ...

__doc__ не пишется только тогда, когда ваш объект имеет тип типа «Тип».

В твоем случае, add_three это функция, и вы можете просто установить __doc__ к любой строке.

В случае, когда вы пытаетесь автоматически генерировать подклассы Unittest.testcas, у вас может быть больше пробега, переопределении их Краткое описание метод.

Это метод, который полосет подлежащую DOCSTRING до первой линии, как видно в нормальном нетестовом выходе; Переопределение было достаточно, чтобы дать нам контроль над тем, что появилось в отчетных инструментах, таких как TeamCity, который был тем, что нам нужно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top