栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何在没有dunder setattr或pdb的情况下监视python中的变量更改

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何在没有dunder setattr或pdb的情况下监视python中的变量更改

好吧,这是一种 缓慢的
方法。可以对其进行修改以监视局部变量的更改(仅按名称)。它是这样工作的:我们执行sys.settrace并在每个步骤中分析obj.attr的值。棘手的是,

'line'
在执行行之前,我们会收到事件(执行了某些行)。因此,当我们注意到obj.attr发生了变化时,我们已经在下一行,并且无法获得前一行的帧(因为没有为每行复制帧,所以它们被修改了)。因此,在我保存
traceback.format_stack
到的每个行事件中
watcher.prev_st
,如果在下一次调用
trace_command
值发生更改时,我们会将保存的堆栈跟踪打印到文件中。在每一行上保存回溯是相当昂贵的操作,因此您必须设置
include

关键字指向您的项目目录列表(或只是项目的根目录),以免观察其他库的工作方式并浪费cpu。

watcher.py

import tracebackclass Watcher(object):    def __init__(self, obj=None, attr=None, log_file='log.txt', include=[], enabled=False):        """ Debugger that watches for changes in object attributes obj - object to be watched attr - string, name of attribute log_file - string, where to write output include - list of strings, debug files only in these directories.    Set it to path of your project otherwise it will take long time    to run on big libraries import and usage.        """        self.log_file=log_file        with open(self.log_file, 'wb'): pass        self.prev_st = None        self.include = [incl.replace('\','/') for incl in include]        if obj: self.value = getattr(obj, attr)        self.obj = obj        self.attr = attr        self.enabled = enabled # important, must be last line on __init__.    def __call__(self, *args, **kwargs):        kwargs['enabled'] = True        self.__init__(*args, **kwargs)    def check_condition(self):        tmp = getattr(self.obj, self.attr)        result = tmp != self.value        self.value = tmp        return result    def trace_command(self, frame, event, arg):        if event!='line' or not self.enabled: return self.trace_command        if self.check_condition(): if self.prev_st:     with open(self.log_file, 'ab') as f:         print >>f, "Value of",self.obj,".",self.attr,"changed!"         print >>f,"###### Line:"         print >>f,''.join(self.prev_st)        if self.include: fname = frame.f_pre.co_filename.replace('\','/') to_include = False for incl in self.include:     if fname.startswith(incl):         to_include = True         break if not to_include:     return self.trace_command        self.prev_st = traceback.format_stack(frame)        return self.trace_commandimport syswatcher = Watcher()sys.settrace(watcher.trace_command)

testwatcher.py

from watcher import watcherimport numpy as npimport urllib2class X(object):    def __init__(self, foo):        self.foo = fooclass Y(object):    def __init__(self, x):        self.xoo = x    def boom(self):        self.xoo.foo = "xoo foo!"def main():    x = X(50)    watcher(x, 'foo', log_file='log.txt', include =['C:/Users/j/PycharmProjects/hello'])    x.foo = 500    x.goo = 300    y = Y(x)    y.boom()    arr = np.arange(0,100,0.1)    arr = arr**2    for i in xrange(3):        print 'a'        x.foo = i    for i in xrange(1):        i = i+1main()


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/651660.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号