これは、興味深い学習体験でした。ここに示されているコードを使用できますか?このデモンストレーションでは、 を使用したときに期待できる出力の種類を理解できるはずですtrace
。
# Functions to trace
# ==================
def baz():
pass
def baz2():
pass
def bar():
baz()
baz2()
def log():
pass
def foo():
bar()
log()
def finish():
pass
def insertVideoEntry():
foo()
finish()
# Names to trace
# ==============
names = list(locals())
# Machinery for tracing
# =====================
import os
import sys
def trace(start, *names):
def tracefunc(frame, event, arg):
if event == 'call':
code = frame.f_code
name = code.co_name
if name in names:
level = -start
while frame:
frame = frame.f_back
level += 1
print('{}{}.{}()'.format(
' ' * level,
os.path.splitext(os.path.basename(code.co_filename))[0],
name))
return tracefunc
sys.settrace(tracefunc)
# Demonstration of tracing
# ========================
trace(2, *names)
insertVideoEntry()
再帰的なデモに興味がある場合は、呼び出された引数の読み出しを使用したこのバリエーションが好きかもしれません。
import os
import sys
def main(discs):
a, b, c = list(range(discs, 0, -1)), [], []
line = '-' * len(repr(a))
print(a, b, c, sep='\n')
for source, destination in towers_of_hanoi(discs, a, b, c):
destination.append(source.pop())
print(line, a, b, c, sep='\n')
def towers_of_hanoi(count, source, via, destination):
if count > 0:
count -= 1
yield from towers_of_hanoi(count, source, destination, via)
yield source, destination
yield from towers_of_hanoi(count, via, source, destination)
def trace(start, *names):
def tracefunc(frame, event, arg):
if event == 'call':
code = frame.f_code
name = code.co_name
if name in names:
level = -start
args = ', '.join(repr(frame.f_locals[name]) for name in
code.co_varnames[:code.co_argcount])
while frame:
frame = frame.f_back
level += 1
print('{}{}.{}({})'.format(
' ' * (level * 4),
os.path.splitext(os.path.basename(code.co_filename))[0],
name, args))
return tracefunc
sys.settrace(tracefunc)
if __name__ == '__main__':
trace(3, 'main', 'towers_of_hanoi')
main(3)