为什么 pyplot.draw() 在通过 Python 的 C API 调用时重新播种 rand()?

Why does pyplot.draw() reseed rand() when called via Python's C API?

我编写了一个产生意外行为的小程序。

我正在使用 Python 的 C API 从我的 C 应用程序中使用 pyplot 的交互模式 (plt.ion()) 绘制一些随机数据。 但是每次我调用 plt.draw() 时,显然 rand() 都会重新播种相同的值。 因此,在下面的示例代码中,每次调用 rand() 都会产生相同的值。

这是一个错误吗?它只在我的机器上吗?我该如何解决这个问题?

我很确定这在一段时间前是有效的。我今天偶然发现了这个, 当我尝试编译并 运行 一些我创建并成功的代码时 几年前测试过 (for the code in this answer).

我正在 运行正在使用 Fedora 23。

这是代码:

#include <Python.h>
#include <stdlib.h>
#include <stdio.h>

int main () {
  Py_Initialize();
  PyRun_SimpleString("import matplotlib");
  PyRun_SimpleString("print matplotlib.__version__");
  PyRun_SimpleString("from matplotlib import pyplot as plt");
  //PyRun_SimpleString("plt.ion()");
  for (int i = 0; i < 10; i++) {
    // rand() returns always the same value?!
    int x = rand();
    int y = rand();
    printf("%d %d\n", x, y);
    // comment out the following line to "fix" rand() behavior:
    PyRun_SimpleString("plt.draw()");
  }
  Py_Finalize();
  return 0;
}

输出是这样的:

$ gcc test.c -I/usr/include/python2.7 -lpython2.7 && ./a.out
1.4.3
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886
1804289383 846930886

此行为的原因是在 Sketch(又名 XKCD)处理代码中有 a call to srand(0).

Michael Droettboom 写了一个 PR 使用本地 RNG 绘制路径,这应该在 1.5.1+ 中修复。