resueltos propias otra lista globales funciones funcion ejercicios ejemplo dentro python function printing docstring

propias - ¿Cómo imprimir Docstring de la función python desde el interior de la función?



lista de funciones de python (8)

Como se señaló muchas veces, usar el nombre de la función es una búsqueda dinámica en el directorio de globals (). Solo funciona en el módulo de la definición y solo para una función global. Si desea averiguar la secuencia de documentación de una función miembro, también deberá buscar la ruta desde el nombre de la clase, lo cual es bastante engorroso, ya que estos nombres pueden ser bastante largos:

def foo(): """ this is foo """ doc = foo.__doc__ class Foo: def bar(self): """ this is bar """ doc = Foo.bar.__doc__

es equivalente a

def foo(): """ this is foo """ doc = globals()["foo"].__doc__ class Foo: def bar(self): """ this is bar """ doc = globals()["Foo"].bar.__doc__

Si desea buscar la cadena de texto de la persona que llama, eso no funcionará de todos modos, ya que su asistente de impresión podría vivir en un módulo completamente diferente con un diccionario de globals () completamente diferente. La única opción correcta es mirar dentro del marco de pila, pero Python no le da el objeto de función que se está ejecutando, solo tiene una referencia al objeto de código "f_code". Pero sigue, ya que también hay una referencia a los "f_globals" de esa función. Por lo tanto, puede escribir una función para obtener el documento de la persona que llama así, y como una variación de él, obtiene su propia cadena de documentación.

import inspect def get_caller_doc(): frame = inspect.currentframe().f_back.f_back for objref in frame.f_globals.values(): if inspect.isfunction(objref): if objref.func_code == frame.f_code: return objref.__doc__ elif inspect.isclass(objref): for name, member in inspect.getmembers(objref): if inspect.ismethod(member): if member.im_func.func_code == frame.f_code: return member.__doc__

y vamos a probarlo:

def print_doc(): print get_caller_doc() def foo(): """ this is foo """ print_doc() class Foo: def bar(self): """ this is bar """ print_doc() def nothing(): print_doc() class Nothing: def nothing(self): print_doc() foo() Foo().bar() nothing() Nothing().nothing() # and my doc def get_my_doc(): return get_caller_doc() def print_my_doc(): """ showing my doc """ print get_my_doc() print_my_doc()

resultados en esta salida

this is foo this is bar None None showing my doc

En realidad, la mayoría de la gente quiere su propia cadena de documentación para presentarla como argumento, pero la función de ayuda llamada puede buscarla por sí misma. Estoy usando esto en mi código unittest, donde a veces es útil llenar algunos registros o usar la cadena de documentos como datos de prueba. Esa es la razón por la cual get_caller_doc () presentado solo busca las funciones de prueba globales y las funciones de miembro de una clase de prueba, pero supongo que eso es suficiente para la mayoría de las personas que desean averiguar acerca de la cadena de documentación.

class FooTest(TestCase): def get_caller_doc(self): # as seen above def test_extra_stuff(self): """ testing extra stuff """ self.createProject("A") def createProject(self, name): description = self.get_caller_doc() self.server.createProject(name, description)

Para definir un get_frame_doc (frame) apropiado con sys._getframe (1) se deja al lector ().

Quiero imprimir el docstring de una función de python desde el interior de la función. por ej.

def my_function(self): """Doc string for my function.""" # print the Docstring here.

Por el momento, estoy haciendo esto directamente después de que se haya definido mi función.

print my_function.__doc__

Pero preferiría que la función lo hiciera por sí misma.

Intenté llamar al print self.__doc__ print self.my_function.__doc__ e print this.__doc__ dentro de mi_función pero esto no funcionó.


Esto debería funcionar (en mis pruebas lo hace, también incluye salida). Probablemente __doc__ usar __doc__ lugar de getdoc, pero me gusta, así que es exactamente lo que usé. Además, esto no requiere que sepas los nombres de la clase / método / función.

Ejemplos tanto para una clase, un método y una función. Dime si no es lo que estabas buscando :)

from inspect import * class MySelfExplaningClass: """This is my class document string""" def __init__(self): print getdoc(self) def my_selfexplaining_method(self): """This is my method document string""" print getdoc(getattr(self, getframeinfo(currentframe()).function)) explain = MySelfExplaningClass() # Output: This is my class document string explain.my_selfexplaining_method() # Output: This is my method document string def my_selfexplaining_function(): """This is my function document string""" print getdoc(globals()[getframeinfo(currentframe()).function]) my_selfexplaining_function() # Output: This is my function document string


Esto funciona:

def my_function(): """Docstring for my function""" #print the Docstring here. print my_function.__doc__ my_function()

en Python 2.7.1

Esto también funciona:

class MyClass(object): def my_function(self): """Docstring for my function""" #print the Docstring here, either way works. print MyClass.my_function.__doc__ print self.my_function.__doc__ foo = MyClass() foo.my_function()

Sin embargo, esto no funcionará solo:

class MyClass(object): def my_function(self): """Docstring for my function""" #print the Docstring here. print my_function.__doc__ foo = MyClass() foo.my_function()

NameError: el nombre global ''my_function'' no está definido


Ha planteado su pregunta como un método de clase en lugar de una función. Los espacios de nombre son importantes aquí. Para una función, print my_function.__doc__ está bien, ya que my_function está en el espacio de nombres global.

Para un método de clase, print self.my_method.__doc__ sería el camino a seguir.

Si no desea especificar el nombre del método, sino pasarle una variable, puede usar las funciones incorporadas hasattr (objeto, atributo) y getattr (obj, attr), que hacen lo que dicen, permitiéndole pasar variables con cadenas como el nombre de un método. p.ej

class MyClass: def fn(self): """A docstring""" print self.fn.__doc__ def print_docstrings(object): for method in dir( object ): if method[:2] == ''__'': # A protected function continue meth = getattr( object, method ) if hasattr( meth , ''__doc__'' ): print getattr( meth , ''__doc__'' ) x = MyClass() print_docstrings( x )


Hay un método bastante simple para hacer esto que nadie ha mencionado aún:

import inspect def func(): """Doc string""" print inspect.getdoc(func)

Y esto hace lo que quieres.

No hay nada elegante pasando aquí. Todo lo que sucede es que al hacer func.__doc__ en una función se difiere la resolución de los atributos el tiempo suficiente para buscar __doc__ en el trabajo como se espera.

Lo uso con docopt para los puntos de entrada del script de consola.


Tratar:

class MyClass(): # ... def my_function(self): """Docstring for my function""" print MyClass.my_function.__doc__ # ...

(*) my_function() dos my_function() después de my_function()


insertando print __doc__ justo después de la declaración de clase, antes de la def __init__ , imprimirá la cadena de documentación en la consola cada vez que inicie un objeto con la clase


def my_func(): """Docstring goes here.""" print my_func.__doc__

Esto funcionará siempre que no cambie el objeto vinculado al nombre my_func .

new_func_name = my_func my_func = None new_func_name() # doesn''t print anything because my_func is None and None has no docstring

Las situaciones en las que harías esto son bastante raras, pero suceden.

Sin embargo, si escribes un decorador como este:

def passmein(func): def wrapper(*args, **kwargs): return func(func, *args, **kwargs) return wrapper

Ahora puedes hacer esto:

@passmein def my_func(me): print me.__doc__

Y esto asegurará que su función se haga una referencia a sí misma (similar a self ) como su primer argumento, por lo que siempre puede obtener el docstring de la función correcta. Si se utiliza en un método, el self habitual self convierte en el segundo argumento.