Python3是否有打印类';s方法调用?
是的,我可以手动在每个方法的定义代码开头添加一行Python3是否有打印类';s方法调用?,python,django,Python,Django,是的,我可以手动在每个方法的定义代码开头添加一行print(“call xxx”)。但这似乎有点傻 例如: class Test(): def a(self): return self.b() def b(self): return self.c() def c(self): return 当您使用X处理Test时,然后调用Test().a(),控制台将打印如下内容: call -> a call -> b
print(“call xxx”)
。但这似乎有点傻
例如:
class Test():
def a(self):
return self.b()
def b(self):
return self.c()
def c(self):
return
当您使用X
处理Test
时,然后调用Test().a()
,控制台将打印如下内容:
call -> a
call -> b
call -> c
因此,您可以看到方法a
如何调用其他方法,这有助于理解一些复杂类的逻辑(例如Django的ListView
)
首先,我使用元类生成X
,即:
import functools
def print_info(func):
@functools.wraps(func)
def magic(*args,**kwargs):
print('call -> %s'%func.__name__)
return func(*args,**kwargs)
return magic
class BlackMeta(type):
def __new__(cls, name, parents, attrs):
new_attrs={}
for k,v in attrs.items():
if callable(v):
new_attrs[k] = print_info(v)
else:
new_attrs[k] = v
return type.__new__(cls, name, parents, new_attrs)
class Test(metaclass=BlackMeta):
def a(self):
return self.b()
def b(self):
return self.c()
def c(self):
return
它起作用了。但当我将BlackMeta
添加到DetailView
的子类中,并调用方法get
时,出现了错误:
所以我放弃了,来到这里寻求帮助。不一定是元类,任何可以显示方法调用顺序的东西都可以。谢谢。您可以使用
sys.settrace
注册一个函数,该函数在函数被调用时被调用,如下所示:
import sys
def trace(frame, event, arg):
if event == 'call':
print("%s (%s line %d)" % (frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno))
return trace
class Test():
def a(self):
return self.b()
def b(self):
return self.c()
def c(self):
return
def do_stuff():
t = Test()
t.a()
sys.settrace(trace)
do_stuff()
输出:
do_stuff (x.py line 16)
a (x.py line 9)
b (x.py line 11)
c (x.py line 13)
只要在任何地方调用任何函数,就会调用跟踪函数,因此
这里的版本将在一个非平凡的程序中产生大量的输出!您只需要在相关的时候打印输出,例如,通过查看
frame.f_code.co_文件名
为什么不使用inspect
模块()。这允许您查看堆栈并查看父调用链是什么
import inspect
class Test():
def a(self):
return self.b()
def b(self):
return self.c()
def c(self):
print inspect.stack()[0]
print inspect.stack()[1]
print inspect.stack()[2]
return
Test().a()
这将打印出:
(<frame object at 0x100271400>, 'test.py', 9, 'c', [' print inspect.stack()[0]\n'], 0)
(<frame object at 0x10025dc60>, 'test.py', 7, 'b', [' return self.c()\n'], 0)
(<frame object at 0x100273a40>, 'test.py', 5, 'a', [' return self.b()\n'], 0)
(,'test.py',9,'c',['print inspect.stack()[0]\n'],0)
(,'test.py',7,'b',['return self.c()\n'],0)
(,'test.py',5,'a',['return self.b()\n'],0)
在每种情况下,函数名都是每个元组中的第四个项,显然,当您深入堆栈时,您跟踪执行链的距离越远
inspect模块允许进行各种自省,如果您想解开复杂代码的逻辑,它是一个不错的选择。我如何将其应用于django项目类视图的运行时方法调用?@Pythoner:好问题;您需要尽早调用
settrace
。我不是Django人,但我认为答案可能是在WSGI脚本中完成(如Apache配置文件中指定的)。本文可能会提供足够的线索:最好在定义代码中添加尽可能少的行,但是谢谢still@Pythoner在你的例子中,RichieHindle的答案似乎更合适,但inspect模块可能非常有用。实际上,你的答案更合适。我只需要找到最后一个方法,并在中为I添加一行[print(I[3])。谢谢。