【问题标题】:changing Python code in the debugger在调试器中更改 Python 代码
【发布时间】:2011-01-28 19:59:24
【问题描述】:

是否有任何调试器允许在调试时更改 Python 代码?

换句话说:发生运行时异常,调试器停止,我以任何我喜欢的方式更改代码,并告诉程序继续。

我知道这种方法的问题,如果我动态地重新定义函数,对函数的引用仍会指向旧定义,依此类推。我对此很满意,因为我只想能够在非常简单的情况下进行小修复。

另一方面,我也对理论上是否可以允许更改 Python 代码而不遇到这些问题感兴趣:即,以某种方式更新对已更改对象的所有引用等。我几乎可以肯定第二个问题的答案是否定的,但如果我错了,我想知道。

编辑:如果我的目标(在发生异常时以交互方式更改代码,然后继续执行)可以在没有调试器的情况下实现 - 那也很好。我不需要使用调试器。

【问题讨论】:

  • 为什么需要调试器?我现在使用 python 有一段时间了,但我从来没有觉得需要一个..
  • @Gabi:因为调试器允许您浏览变量以查看它们的值、动态执行函数并检查代码是否正在运行,而不是依赖于打印语句。如果您要对复杂的逻辑或大量数据进行故障排除,调试器将变得非常宝贵。
  • @Jordan:在过去的 30 年中,我曾经使用调试器在 C 核心文件中查找堆栈跟踪。您建议的所有事情都可以通过其他方式完成。调试器并不是真正的“无价之宝”。这只是一种偏好。
  • @max:这通常是一个非常糟糕的主意。无论有没有调试器,您所说的通常都是毫无意义的。简单情况下的小修复只是“编辑并重新运行”。是什么阻止您编辑和重新运行?
  • @S Lott 用例:我在断言捕获的函数中出错。执行到该点需要几分钟。我知道该函数没有在任何地方作为参数传递等等。我可以修复代码并继续执行,而不必再等几分钟。感谢您的 cmets。

标签: python debugging python-3.x


【解决方案1】:

name = (input("输入姓名:"))

如果名称 == “e”: print("这个词有一个字母e")

其他: print("这个词没有字母e")

【讨论】:

  • 您没有回答与该问题相关的任何内容。坦率地说,我很困惑为什么这与查找调试器有关。
【解决方案2】:

由于您可以随时以您想要的方式更改常规类的内容,因此无需更新对对象的引用:您只需使用新方法和其他属性更新类的__dict__

问题在于对函数的引用:您无法在不更改其标识的情况下更新函数。您可以使用总是按名称查找真实函数的代理函数,并且您可以随时更改真实函数。否则,您计划您的代码,以便它不会长时间存储函数引用;一旦一个函数被更新,它很快就会被名称查找,但是传递到某个地方的旧引用将继续执行更长的时间。

如果您想在不严重停机的情况下升级一个长时间运行的系统,那么这种修补程序将是有意义的:您暂停它片刻以一致地升级多个类和功能,然后取消暂停。 AFAIK Erlang 以类似的方式进行即时更新。

【讨论】:

  • +1 我不知道不改变身份就不能改变功能。
【解决方案3】:

理论上是否可以允许更改 Python 代码

是的。可以“即时”更新代码对象。 Python VM 中似乎没有任何东西可以阻止这一点。没有对校验和或任何东西进行持续验证。

以某种方式更新对已更改对象的所有引用,

这甚至没有意义。一旦更改了类级别的方法定义,“更新”所有引用甚至都没有必要或不明智。代码只在它存在的地方发生了变化。

这就是调试器不好的原因。它们似乎会导致模糊不清的思维。对调试器考虑太多意味着对手头的真正问题考虑得太少。

TDD 是一项好得多的投资。小型、可管理的单元测试运行迅速,并提供持久的证据证明一切正常。

http://en.wikipedia.org/wiki/Test-driven_development

【讨论】:

    【解决方案4】:

    是的,pdb 可以做到这一点。虽然您必须在另一个编辑器中进行编辑,并且更改将被忽略,直到您重新启动。

    但是由于您要做的只是微小的更改,因此这不是问题。但是您不能更改正在运行的代码(除了重新加载,见下文),因为更改代码将意味着代码和状态不同步。

    您可以使用调试器来测试您想要进行的更改。您可以根据需要粘贴代码来更改它,从而在不重新运行整个程序的情况下测试它是否正确。但在这种情况下,您无需编辑文件。

    (在某些特定情况下,您可以通过仔细使用“reload()”来避免不重新启动,但这可能不值得。)

    【讨论】:

      【解决方案5】:

      您可以使用 xreload 更新正在运行的 python 进程中的代码:

      http://svn.python.org/projects/sandbox/trunk/xreload/xreload.py

      有很多限制,它们列在文件的顶部。我不确定这是否可以处理您想要的情况 - 您是否真的想阻止异常传播?这需要的不仅仅是更新正在运行的程序。

      【讨论】:

      • 谢谢 - 这是一个有趣的工具,但我现在意识到,由于涉及的复杂性,它可能不值得这样做。
      猜你喜欢
      • 2019-08-10
      • 2012-05-04
      • 1970-01-01
      • 2012-08-15
      • 2022-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多