Estoy tratando de aprender cómo funciona una aplicación. Y para esto, estoy insertando comandos de depuración como la primera línea del cuerpo de cada función con el objetivo de registrar el nombre de la función, así como el número de línea (dentro del código) donde envío un mensaje a la salida del registro. Finalmente, dado que esta aplicación se compone de muchos archivos, quiero crear un solo archivo de registro para poder comprender mejor el flujo de control de la aplicación.
Esto es lo que sé:
para obtener el nombre de la función, puedo usar
function_name.__name__
pero no quiero usar el nombre_función (para poder copiar y pegar rápidamente un genéricoLog.info("Message")
en el cuerpo de todas las funciones). Sé que esto podría hacerse en C usando__func__
macro, pero no estoy seguro de Python.para obtener el nombre del archivo y el número de línea, he visto que (y creo que) mi aplicación está usando la
locals()
función Python pero en una sintaxis de la que no estoy completamente consciente, por ejemplo:options = "LOG.debug('%(flag)s : %(flag_get)s' % locals())
y lo intenté usando likeLOG.info("My message %s" % locals())
que produce algo como{'self': <__main__.Class_name object at 0x22f8cd0>}
. ¿Alguna entrada sobre esto por favor?Sé cómo usar el registro y agregarle un controlador para registrarlo en un archivo, pero no estoy seguro de si se puede usar un solo archivo para registrar todos los mensajes de registro en el orden correcto de las llamadas a funciones en el proyecto.
Agradecería mucho cualquier ayuda.
¡Gracias!
import pdb; pdb.set_trace()
y luego recorrer el código de forma interactiva. Eso puede ayudarlo a rastrear el flujo del programa.Respuestas:
Tiene algunas preguntas marginalmente relacionadas aquí.
Empezaré con el más fácil: (3). Con
logging
puede agregar todas las llamadas a un solo archivo de registro u otro destino de salida: estarán en el orden en que ocurrieron en el proceso.A continuación: (2).
locals()
proporciona un dictamen del alcance actual. Por lo tanto, en un método que no tiene otros argumentos, tiene unself
alcance, que contiene una referencia a la instancia actual. El truco que se está utilizando y que lo está confundiendo es el formato de cadena usando un dict como el RHS del%
operador."%(foo)s" % bar
será reemplazado por el valor debar["foo"]
.Finalmente, puede usar algunos trucos de introspección, similares a los que usa para
pdb
registrar más información:Esto registrará el mensaje pasado, más el nombre de la función (original), el nombre del archivo en el que aparece la definición y la línea en ese archivo. Eche un vistazo a inspeccionar: inspeccionar objetos vivos para obtener más detalles.
Como mencioné en mi comentario anteriormente, también puede acceder a un
pdb
mensaje de depuración interactivo en cualquier momento insertando la líneaimport pdb; pdb.set_trace()
y volviendo a ejecutar su programa. Esto le permite recorrer el código, inspeccionando los datos a su elección.fuente
'%(foo)s : %(bar)s'
también imprimiría elbar["foo"]
valor de? ¿O es algo diferente a tu ejemplo?%(<foo>)s
se reemplaza por el valor del objeto al que se hace referencia en el dict by<foo>
. Hay más ejemplos / detalles en docs.python.org/library/stdtypes.html#string-formattingLa respuesta correcta para esto es usar la
funcName
variable ya proporcionadaLuego, en cualquier lugar que desee, simplemente agregue:
Salida de ejemplo de un script en el que estoy trabajando en este momento:
fuente
getLogger(__name__)
logging.getLogger('root')
probablemente no es lo que espera, no es elroot
registrador, sino un registrador ordinario con el nombre 'root'.funcname
,linename
Ylineno
proporcionar información acerca de la última función que hizo el registro.Si tiene un contenedor de registrador (por ejemplo, registrador singleton), entonces la respuesta de @ Synthesizerpatel podría no funcionar para usted.
Para averiguar las otras personas que llaman en la pila de llamadas, puede hacer lo siguiente:
fuente
logging
soportes clase de pila nivel de saltar fuera de la caja: métodos comolog()
,debug()
, etc. ahora aceptar unstacklevel
argumento. Consulte los documentos .