在大型Python代码库中从效果追溯到原因

在大型Python代码库中从效果追溯到原因,python,debugging,Python,Debugging,我在Django有一个相当大的项目,这是一个相当大的框架,我使用了相当多的应用程序、中间件、上下文处理器等。规模意味着当代码库的一部分运行于我不希望的请求时,很难确定为什么会这样做。直接代码检查非常耗时,在调试器中单步检查整个请求也是如此 在这个特殊的例子中,我的问题是我在每个响应上都设置了“Vary:Cookie”,包括一些我想要大量缓存的响应,以及我不需要任何Cookie的响应。我怀疑,但不知道如何证明,某些中间件或上下文处理器正在访问request.session,即使它不使用结果——尽管

我在Django有一个相当大的项目,这是一个相当大的框架,我使用了相当多的应用程序、中间件、上下文处理器等。规模意味着当代码库的一部分运行于我不希望的请求时,很难确定为什么会这样做。直接代码检查非常耗时,在调试器中单步检查整个请求也是如此

在这个特殊的例子中,我的问题是我在每个响应上都设置了“Vary:Cookie”,包括一些我想要大量缓存的响应,以及我不需要任何Cookie的响应。我怀疑,但不知道如何证明,某些中间件或上下文处理器正在访问
request.session
,即使它不使用结果——尽管它可能是间接访问,例如通过
request.user
。当然,它可能完全是另一回事


在Python中,如何在一个大的代码库中从一个结果(“Varie头被添加到响应”)追溯到它的原因?

这里有一个想法:对django HttpResponse类进行monkey补丁,以便在设置的头是
Varie
时,它的
setitem\uuuuuuuuuuuuuuuu>方法会引发异常。在创建时,您可以从一个其他不做任何事情的中间件处理这个问题。它应该可以很好地从设置标题的行中回溯

class MonkeyPatchMiddleware(object):

   def __init__(self):
       from django.http import HttpResponse

       original_set_item = HttpResponse.__setitem__

       def __setitem__(self, header, value):
           if header == "Vary":
               raise ValueError
           original_set_item(self, header, value)

       HttpResponse.__setitem__ = __setitem__

在django设置文件的中间件堆栈中,首先安装中间件。

Hello。我不熟悉django,但是如果您需要找到做了什么,
A['x']=y
,并且
A
不是内置对象,那么您可以用自己的来替换一个..\uuuuuuuuSetItem\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,只需打印调用堆栈,它将引导您找到导致调用堆栈的原因。另一个变体是编写一个调试器,它将逐行执行您的程序,并每次检查您所需的头是否已附加到特定对象。谢谢,@alex_jordan,这是一个好的开始。如何以编程方式打印调用堆栈?在这种情况下,我相信如果在其他地方设置了标志,则会添加头,因此调用堆栈会告诉我是哪个标志触发了它;但是我可以跟踪字段分配以查找何时设置了标志吗?最后,所讨论的对象是按请求分配的。我可以为所有实例使用它们来自的类进行修补吗?Jamey,我下面提供的解决方案就是这样做的,并使用django错误报告,这样您就不必担心自己打印堆栈跟踪的细节了。谢谢!我发现在我的应用程序的
views.py
中尝试这一点比添加中间件更方便。回溯告诉我是
SessionMiddleware.process\u response
调用了
patch\u vary\u headers
,但为了找出原因,我需要发现是什么设置了
request.session.accessed
。在
SessionBase.accessed=property(lambda-self:False,raise\u on\u-true)中进行Monkey修补
为我找到了一个关于真正根本原因的回溯。