当前位置: 首页 > 面试题库 >

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

栾景胜
2023-03-14
问题内容

有一个大型的python项目,其中一类的一个属性在某处只是错误的值。

它应该是sqlalchemy.orm.attributes.InstrumentedAttribute,但是当我运行测试时,它是恒定值,比方说字符串

有某种方法可以在调试模式下运行python程序,并在每一步自动通过代码行之后运行一些检查(如果变量更改了类型)?

PS我知道如何在检查和属性装饰器的帮助下记录类实例的属性更改。可能在这里我可以将此方法与元类一起使用…

但是有时候我需要更通用,更强大的解决方案…


问题答案:

好吧,这是一种 缓慢的
方法。可以对其进行修改以监视局部变量的更改(仅按名称)。它是这样工作的:我们执行sys.settrace并在每个步骤中分析obj.attr的值。棘手的是,'line'在执行行之前,我们会收到事件(执行了某些行)。因此,当我们注意到obj.attr发生了变化时,我们已经在下一行,并且无法获得前一行的帧(因为没有为每行复制帧,所以它们被修改了)。因此,在我保存traceback.format_stack到的每个行事件中watcher.prev_st,如果在下一次调用trace_command值发生更改时,我们会将保存的堆栈跟踪打印到文件中。在每一行上保存回溯是相当昂贵的操作,因此您必须设置include
关键字指向您的项目目录列表(或只是项目的根目录),以免观察其他库的工作方式并浪费cpu。

watcher.py

import traceback

class 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_code.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_command
import sys
watcher = Watcher()
sys.settrace(watcher.trace_command)

testwatcher.py

from watcher import watcher
import numpy as np
import urllib2
class X(object):
    def __init__(self, foo):
        self.foo = foo

class 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+1

main()


 类似资料:
  • 我不想再使用powermock了。因为junit5开始模拟静态类。因此,我试图摆脱powermock方法。 当我使用PowerMock时,我可以很容易地发现一个具有私有构造函数的类,然后我调用静态方法。 这是我代码的一部分(当我使用PowerMock时) 在我做了MessageValidationUtils.class的间谍对象后,我正在测试这个: 经过一些研究,我找不到任何与监视一个具有私有构造

  • 问题内容: 这个问题已经在这里有了答案 : 如何在没有换行符或空格的情况下进行打印? (22个答案) 3年前关闭。 我想知道在打印某些内容时如何删除其他空格。 就像我这样做时: 输出将是: 但是我想要: 有什么办法吗? 问题答案: 如果您不需要空格,请不要使用。使用字符串串联或格式化。 级联: 格式: 后者要灵活得多,请参见方法文档和“ 格式化字符串语法” 部分 。 您还将遇到较早的格式化样式:

  • 问题内容: 我正在尝试在HTML页面上显示一些JavaScript变量。我第一次使用它,但是当调用该函数时,它用于覆盖当前页面。 在四处搜寻之后,普遍的共识是人们对此不太喜欢。还有哪些其他选择? 我找到了一个建议使用的页面,但该页面写于2005年。 问题答案: 几乎是要走的路。以下是使用它的几种方法: HTML JavaScript 如果您只想更新I 的一部分,通常只需要添加一个类似或类的空元素,

  • 我在项目中定义了一个模型类。和往常一样,它有一些私有变量和公共的获取者和设置者 假设在其他类中我使用这个模型,就像 然后person的私有变量保存值“my name”,我使用类的public getter访问变量,如 所以据我所知的人。getMark()返回私有变量名的引用,因此如果我修改局部变量“localMark”,它将影响Person类的私有变量,因此它会破坏变量的私有属性 前任: 我猜大多

  • 我正在尝试安装一个没有依赖项的python模块。 我跑: 但是这个安装依赖项,任何想法怎么能做到这一点?

  • 问题内容: 我是Python的新手,正在尝试安装此模块:http : //www.catonmat.net/blog/python-library-for-google- search/ 目录中没有setup.py,但是有以下文件: 有人可以告诉我如何设置或使用此模块吗? 谢谢! 问题答案: 在系统上开始使用该代码的最简单方法是: 将文件放入计算机上的目录中, 将该目录的路径添加到您的PYTHON