这是一个使用 FuncAnimation 没有自定义类的示例:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def animate(data, im):
im.set_data(data)
def step():
while True:
# replace this with Conway's Game of Life logic
data = np.random.randn(10, 10)
yield data
fig, ax = plt.subplots()
im = ax.imshow(np.random.randn(10, 10), interpolation='nearest')
ani = animation.FuncAnimation(
fig, animate, step, interval=10, repeat=True, fargs=(im, ))
plt.show()
当您在函数中使用 yield(而不是 return)时,它会使函数成为generator。生成器函数保存状态。每次调用next
生成器返回的迭代器时,执行流程都会从它停止的地方(从最后一个 yield 表达式)开始。这就是为什么生成器是一种避免全局变量的方法——可能的全局变量只是生成器函数中的局部变量,它们的状态在调用next
.
顺便说一句,“永远不要使用全局变量”的警告不够精确。我们一直使用全局变量。每次在模块级别导入模块时,模块对象都是全局的。每次在模块级别定义函数或类时,它都是全局的。使用全局变量并没有错(尽管从函数内部访问全局变量确实比访问函数的局部变量要慢。不过,请注意预优化)。
也许建议改为“尽量不要使用改变状态的全局变量”。改变全局值不好的原因是因为改变全局的每个函数都变得默默相关。该功能不再可以作为一个孤立的代码单元来理解和测试。程序员用来解决问题的主要工具是将大问题分解成更小的部分。函数和类有助于将问题分解成更小的部分。但是当你使用变异全局变量时,你会失去这个好处。大脑现在必须立即了解整个模块才能理解代码。