¿Cómo configuro mediante progtwigción la cadena de documentos?

Tengo una función de envoltorio que devuelve una función. ¿Hay una manera de establecer mediante progtwigción la cadena de documentos de la función devuelta? Si pudiera escribir a __doc__ , haría lo siguiente:

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

Entonces podria hacer

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

Sin embargo, dado que __doc__ es de solo lectura, no puedo hacer eso. ¿Cuál es la forma correcta?


Edit: Ok, quería mantener esto simple, pero por supuesto esto no es lo que realmente estoy tratando de hacer. Aunque en general, __doc__ se puede escribir en mi caso, no lo es.

Estoy tratando de crear testcases para unittest automáticamente. Tengo una función de contenedor que crea un objeto de clase que es una subclase de 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 

Si creo esta clase e bash establecer la cadena de testSomething de testSomething , testSomething un error:

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

Pasaría la cadena de documentos a la función de fábrica y usaría el type para construir manualmente la clase.

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

Un método instant obtiene su cadena de documentos de su __func__ . Cambiar la cadena de __func__ de __func__ en __func__ lugar. (El atributo __doc__ de las funciones se puede escribir.)

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

De los 2.7 documentos :

Métodos definidos por el usuario

Un objeto de método definido por el usuario combina una clase, una instancia de clase (o Ninguna) y cualquier objeto llamable (normalmente una función definida por el usuario).

Atributos especiales de solo lectura: im_self es el objeto de instancia de clase, im_func es el objeto de función; im_class es la clase de im_self para métodos enlazados o la clase que solicitó el método para métodos no enlazados; __doc__ es la documentación del método (igual que im_func.__doc__ ); __name__ es el nombre del método (igual que im_func.__name__ ); __module__ es el nombre del módulo en el que se definió el método, o Ninguno si no está disponible.

Cambiado en la versión 2.2: im_self se usa para referirse a la clase que definió el método.

Modificado en la versión 2.6: para 3.0 compatibilidad hacia adelante, im_func también está disponible como __func__ , y im_self como __self__ .

Sólo usa decoradores. Aquí está tu caso:

 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' 

Este es un caso de uso similar: la ayuda dinámica de Python y la generación autocompletada

Esto es una adición al hecho de que el atributo __doc__ de clases de tipo de type no se puede cambiar. El punto interesante es que esto solo es cierto siempre que la clase se cree utilizando type. Tan pronto como uses una metaclase, puedes cambiar __doc__ .

El ejemplo utiliza el módulo abc (AbstractBaseClass). Funciona utilizando una metaclase especial de ABCMeta

 import abc class MyNewClass(object): __metaclass__ = abc.ABCMeta MyClass.__doc__ = "Changing the docstring works !" help(MyNewClass) 

resultará en

 """ Help on class MyNewClass in module __main__: class MyNewClass(__builtin__.object) | Changing the docstring works ! """ 

Supongo que esto debería ser un comentario, pero aún así estoy acumulando mis primeros 50 puntos …

__doc__ no se puede escribir solo cuando su objeto es de tipo ‘tipo’.

En su caso, add_three es una función y simplemente puede establecer __doc__ a cualquier cadena.

En el caso de que esté tratando de generar automáticamente subclases de Unittest.TestCase, es posible que tenga más millas sobrepasando su método de descripción corta .

Este es el método que elimina la cadena de documentos subyacente hasta la primera línea, como se ve en la salida de prueba de unidad normal; anularlo fue suficiente para darnos control sobre lo que aparecía en herramientas de informes como TeamCity, que era lo que necesitábamos.