6

如何查看 Python 脚本中调用了哪些函数以及所有变量值?

我刚刚发现了 Python 的不确定性包,我想真正弄清楚它是如何工作的,这样我就可以向我的老板解释它。

基本上,我看不到不确定性是如何实际计算的。这可能是因为我还不知道 Python 是如何工作的。

对于初学者,我怎样才能看到c是如何计算的?

import uncertainties
from uncertainties import ufloat

a = ufloat(1,3)
b = ufloat(2,4)

c = a + b  # How does this work??

print c
4

3 回答 3

1

如果你想看看事情是如何计算的,pdb确实是一种解决方案。

但是,对于像 之类的调试器pdb,很难对正在发生的事情进行高级概述。这就是为什么阅读代码也很有用的原因。例如,如果你想知道什么a+b是,你可以检查是否type(a).__add__存在,因为如果存在,它会处理加法。不确定性包就是这种情况。

也就是说,__add__确实是通过通用机制在不确定性中实现的,而不是专门针对它进行编码的,所以我可以告诉你其实现背后的想法,因为这似乎是你最终要寻找的。

在您的示例中,a并且bVariable对象:

>>> from uncertainties import ufloat                                            
>>> a = ufloat(1, 3)
>>> b = ufloat(2, 4)
>>> type(a)
<class 'uncertainties.Variable'>

然后c = a + b实际上是 和 的线性函数由其关于和的导数表示:abab

>>> c = a + b
>>> type(c)
<class 'uncertainties.AffineScalarFunc'>
>>> c.derivatives
{1.0+/-3.0: 1.0, 2.0+/-4.0: 1.0}

如果你知道一个函数关于它的变量的导数,你可以很容易地从它的变量的标准差中得到它的标准差的近似值

因此,实施不确定性包背后的主要思想是值是:

  • 随机变量,如 x = 3.14±0.0.1 和 y = 0±0.01(Variable对象),由它们的标准偏差描述,
  • 或函数的线性逼近(AffineScalarFunc对象:“仿射”因为它们是线性的,“标量”因为它们的值是实数的,而“func”因为它们是函数)。

举一个更复杂的例子,z = 2*x+sin(y) 在 (x, y) = (3.14, 0) 中近似为 2*x + y。在实现中,由于近似是线性的,因此只存储变量的导数:

>>> x = ufloat(3.14, 0.01)
>>> y = ufloat(0, 0.01)
>>> from uncertainties.umath import sin
>>> z = 2*x + sin(y)
>>> type(z)
<class 'uncertainties.AffineScalarFunc'>
>>> z.derivatives
{3.14+/-0.01: 2.0, 0.0+/-0.01: 1.0}

因此,不确定性包所做的主要工作是计算任何涉及变量的函数的导数。这是通过自动微分的有效方法完成的。具体来说,当您执行类似的操作时a+b,Python 会自动调用该Variable.__add__()方法,该方法通过计算 的a+b对其变量的导数来创建一个新的线性函数(导数均为 1,因为 的导数aa1,并且相同为b)。更一般地,一个添加函数,而不是纯变量:f(a,b) + g(a,b)关于a和的导数b是用链式法则计算的。这就是自动微分的工作原理,这就是在不确定性包中实现的。这里的关键功能是uncertainties.wrap()。是整个包中最大也是最复杂的一个函数,但是代码大部分是注释的,具体方法可以参考。

导数然后给你最终函数的标准差作为变量标准差的函数(代码AffineScalarFunc.std_dev()很简单:更困难的任务是自动计算导数)。

于 2013-08-17T13:26:43.043 回答
1

忽略模块的具体情况uncertainties,Python提供了sys.settrace函数,可以用来实现Smiliey应用跟踪器之类的东西

例如,来自文档

在一个终端窗口中,运行 monitor 命令:

$ smiley monitor

在第二个终端窗口中,使用笑脸来运行应用程序。此示例使用笑脸源树中 test_app 目录中的 test.py。

$ smiley run ./test.py
args: ['./test.py']
input = 10
Leaving c() [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Leaving b()
Leaving a()

监控会话将显示应用程序的执行路径和局部变量。

Starting new run: ./test.py
test.py:   1: import test_funcs
test.py:   1: import test_funcs
test_funcs.py:   1: import sys
test_funcs.py:   1: import sys
test_funcs.py:   3: def gen(m):
test_funcs.py:   8: def c(input):
于 2013-08-17T13:59:39.763 回答
0

你可以看看 Python 调试器: http: //docs.python.org/2/library/pdb.html

您可能知道,调试器旨在让您观察程序的各个部分在执行期间的移动。

您可能还想在https://github.com/lebigot/uncertainties/上查看 Uncertainties 包的源代码

于 2013-08-16T00:18:43.910 回答