2014-06-26 17 views
13

Ich baue gerade ein ziemlich komplexes System in Python, und wenn ich debugge, gebe ich oft einfache Druckanweisungen in mehrere Skripte. Um den Überblick zu behalten, möchte ich oft auch den Dateinamen und die Zeilennummer ausdrucken, wo sich die Druckanweisung befindet. Ich kann natürlich tun, manuell oder mit etwas wie folgt aus:Python-Debugging: Dateiname und Zeilennummer, von der eine Funktion aufgerufen wird?

from inspect import currentframe, getframeinfo 
print getframeinfo(currentframe()).filename + ':' + str(getframeinfo(currentframe()).lineno) + ' - ', 'what I actually want to print out here' 

die druckt etwas wie:

filenameX.py:273 - was ich will eigentlich hier auszudrucken

um es einfacher zu machen, möchte ich in der Lage sein, etwas zu tun wie:

print debuginfo(), 'what I actually want to print out here' 
Also habe ich es in eine Funktion irgendwo setzen und versuchte zu tun:

from debugutil import debuginfo 
print debuginfo(), 'what I actually want to print out here' 
print debuginfo(), 'and something else here' 

leider bekomme ich:

debugutil.py:3 - what I actually want to print out here 
debugutil.py:3 - and something else here 

Es druckt den Dateinamen und die Zeilennummer, an dem ich die Funktion definiert ist, statt der Zeile, auf der ich debuginfo() anrufe. Dies ist offensichtlich, da sich der Code in der Datei debugutil.py befindet.

Also meine Frage ist eigentlich: Wie bekomme ich den Dateinamen und die Zeilennummer, von denen diese debuginfo() Funktion aufgerufen wird? Alle Tipps sind willkommen!

+0

Verwenden das Modul 'logging' und konfigurieren Sie den Formatierer: https://docs.python.org/2/library/logging.html#logrecord-attributes. Das Tornado-Web-Framework hat tatsächlich ein Format, das diesem sehr ähnlich ist, also könnten Sie wahrscheinlich ihren Code verwenden: http://tornado.readthedocs.org/en/latest/_modules/tornado/log.html#LogFormatter – Blender

Antwort

26

Die Funktion inspect.stack() eine Liste von frame records zurückgibt, mit dem Anrufer beginnen und bewegend aus, mit dem Sie die gewünschten Informationen erhalten verwenden können:

from inspect import getframeinfo, stack 

def debuginfo(message): 
    caller = getframeinfo(stack()[1][0]) 
    print "%s:%d - %s" % (caller.filename, caller.lineno, message) 

def grr(arg): 
    debuginfo(arg) 

grr("aargh") 

Ausgang:

example.py:8 - aargh 
+0

Ok, das ist gut. –

+0

Danke für Ihre Hilfe! Ich werde das in so ziemlich jedem Projekt verwenden, an dem ich arbeite! Sie, mein Herr, haben mein Leben nur ein bisschen besser gemacht, dass ich es jetzt offiziell als "fantastisch" bezeichnen kann! – kramer65

+0

Das ist großartig! Es gab eine Funktion im Django, bei der ich nicht herausfinden konnte, woher es aufgerufen wurde. – Sankalp

0

Setzen Sie einfach den Code in eine Funktion geschrieben:

from inspect import currentframe, getframeinfo 

def my_custom_debuginfo(message): 
    print getframeinfo(currentframe()).filename + ':' + str(getframeinfo(currentframe()).lineno) + ' - ', message 

und dann verwenden, wie Sie wollen:

# ... some code here ... 
my_custom_debuginfo('what I actually want to print out here') 
# ... more code ... 

ich Ihnen diese Funktion in einem separaten Modul setzen empfehlen, auf diese Weise Sie kann es jedes Mal wiederverwenden, wenn Sie es brauchen.

+0

Das habe ich schon gemacht , und dann druckt es den Dateinamen und die Zeilennummer des Moduls, in dem die Funktion ist, nicht, wo ich die Funktion anrufe. Irgendwelche anderen Ideen? – kramer65