2011-07-25 10 views
42

En C++, puedo imprimir la salida de depuración de esta manera:¿Cómo determinar el archivo, la función y el número de línea?

printf(
    "FILE: %s, FUNC: %s, LINE: %d, LOG: %s\n", 
    __FILE__, 
    __FUNCTION__, 
    __LINE__, 
    logmessage 
); 

¿Cómo puedo hacer algo similar en Python?

+1

Siempre registro de errores de impresión así? Eso es notable, ya que no hay una función 'print' en C++. –

+1

@Tomalak typo, en el hilo de Python ahora. :) – pengdu

+1

Una vez que te vas Python, nunca regresas (mucho). –

Respuesta

58

Hay un módulo llamado inspect que proporciona esta información.

Ejemplo de uso:

import inspect 

def PrintFrame(): 
    callerframerecord = inspect.stack()[1] # 0 represents this line 
              # 1 represents line at caller 
    frame = callerframerecord[0] 
    info = inspect.getframeinfo(frame) 
    print info.filename      # __FILE__  -> Test.py 
    print info.function      # __FUNCTION__ -> Main 
    print info.lineno       # __LINE__  -> 13 

def Main(): 
    PrintFrame()        # for this line 

Main() 

Sin embargo, recuerde que hay una manera más fácil de obtener el nombre del archivo que se está ejecutando:

print __file__ 
9

Por ejemplo

import inspect 
frame = inspect.currentframe() 
# __FILE__ 
fileName = frame.f_code.co_filename 
# __LINE__ 
fileNo = frame.f_lineno 

Hay más aquí http://docs.python.org/library/inspect.html

+1

Y una forma simple de obtener el archivoNo: 'fileNo = frame.f_lineno' – ahui

+0

@hilojack - gracias - ¡siéntase libre de editar la respuesta! –

3
import inspect 
    . 
    . 
    . 
def __LINE__(): 
    try: 
     raise Exception 
    except: 
     return sys.exc_info()[2].tb_frame.f_back.f_lineno 

def __FILE__(): 
    return inspect.currentframe().f_code.co_filename 
    . 
    . 
    . 
print "file: '%s', line: %d" % (__FILE__(), __LINE__()) 
7

Sobre la base de la respuesta de geowar:

class __LINE__(object): 
    import sys 

    def __repr__(self): 
     try: 
      raise Exception 
     except: 
      return str(sys.exc_info()[2].tb_frame.f_back.f_lineno) 

__LINE__ = __LINE__() 

Si normalmente desea utilizar en, por ejemplo __LINE__print (o en cualquier otro momento en que se tome implícita str() o repr()), lo anterior le permitirá omitir el () s.

(extensión obvia para añadir un __call__ deja como ejercicio para el lector.)

1

Yo también estaba interesado en un comando __LINE__ en Python. Mi punto de partida era https://stackoverflow.com/a/6811020 y lo extendí con un objeto de metaclase. Con esta modificación tiene el mismo comportamiento que en C++.

import inspect 

class Meta(type): 
    def __repr__(self): 
     # Inspiration: https://stackoverflow.com/a/6811020 
     callerframerecord = inspect.stack()[1] # 0 represents this line 
     # 1 represents line at caller 
     frame = callerframerecord[0] 
     info = inspect.getframeinfo(frame) 
     # print(info.filename) # __FILE__  -> Test.py 
     # print(info.function) # __FUNCTION__ -> Main 
     # print(info.lineno) # __LINE__  -> 13 
     return str(info.lineno) 

class __LINE__(metaclass=Meta): 
    pass 

print(__LINE__) # print for example 18 
Cuestiones relacionadas