Das Verhalten der Funktionen in der ausführbaren Datei kann mit einem Dekorator geändert werden:
#!/usr/bin/env python
from module1 import foo
from module2 import bar
def trace(f):
def tracewrapper(*arg, **kw):
arg_str=','.join(['%r'%a for a in arg]+['%s=%s'%(key,kw[key]) for key in kw])
print "%s(%s)" % (f.__name__, arg_str)
return f(*arg, **kw)
return tracewrapper
verbose_functions=[foo,bar] # add whatever functions you want logged here
for func in verbose_functions:
globals()[func.func_name]=trace(func)
Da Sie nur die Definition der Funktionen im Namensraum der ausführbaren Datei ändern, bleiben die Funktionen der Module unangetastet. Wenn die Funktion eines Moduls die Funktion eines anderen Moduls aufruft, wird sie nicht durch Trace gekennzeichnet und es wird keine Protokollanweisung erzeugt.
Wenn Sie Funktionsaufrufe nur protokollieren möchten, wenn sie direkt von main() kommen, dann könnten Sie einen Trace-Dekorator wie diesen verwenden:
import traceback
def trace(f,filename,funcname):
def tracewrapper(*arg, **kw):
stacks=traceback.extract_stack()
(s_filename,s_lineno,s_funcname,s_text)=stacks[-2]
# Alternatively, you can search the entire call stack
# for (s_filename,s_lineno,s_funcname,s_text) in stacks:
if s_filename.endswith(filename) and s_funcname==funcname:
arg_str=','.join(['%r'%a for a in arg]+
['%s=%s'%(key,kw[key]) for key in kw])
print "%s(%s)" % (f.__name__, arg_str)
return f(*arg, **kw)
return tracewrapper
verbose_functions=[foo,bar] # add whatever functions you want logged here
for func in verbose_functions:
# You can pass the module's filename and the function name here
globals()[func.func_name]=trace(func,'test.py','main')
Beachten Sie, dass mit der obigen Kurve
def baz():
foo(3,4)
def main():
foo(1,2,'Hi')
bar(x=3)
baz()
würde die foo(1,2,'Hi')
y bar(x=3)
Anrufe, aber no foo(3,4)
da diese Anruf nicht kommt direkt von main. Sie kommt jedoch indirekt von main, denn main ruft baz
. Wenn Sie die Daten protokollieren möchten foo(3,4)
anrufen, dann sollten Sie Schleife durch den gesamten Stapel:
import traceback
def trace(f,filename,funcname):
def tracewrapper(*arg, **kw):
stacks=traceback.extract_stack()
for (s_filename,s_lineno,s_funcname,s_text) in stacks:
if s_filename.endswith(filename) and s_funcname==funcname:
arg_str=','.join(['%r'%a for a in arg]+
['%s=%s'%(key,kw[key]) for key in kw])
print "%s(%s)" % (f.__name__, arg_str)
return f(*arg, **kw)
return tracewrapper
0 Stimmen
"Akzeptieren" orientierte Programmierung ;-)