我正在撰写康威的生命游戏实施。我的第一次尝试只是在每次更新后使用matplotlib的imshow在1和0的NxN板上绘制板。但是,这不起作用,因为程序在显示情节时会暂停。你必须关闭图以获得下一个循环迭代。
我发现在matplotlib中有一个动画包,但它没有(或给出)变量,所以我见过的每个实现(偶数matplotlib's documentation)依赖于全局变量。
所以这里有两个问题:
1)这是一个可以使用全局变量的地方吗?我一直都认为这是永远一个好主意,但这只是教条吗?
2)你如何在没有全局变量的python中做这样的动画(即使它意味着放弃matplotlib,我猜;标准库总是首选)。
答案 0 :(得分:4)
这些只是示例程序。您可以使用object而不是全局变量,如下所示:
class GameOfLife(object):
def __init__(self, initial):
self.state = initial
def step(self):
# TODO: Game of Life implementation goes here
# Either assign a new value to self.state, or modify it
def plot_step(self):
self.step()
# TODO: Plot here
# TODO: Initialize matplotlib here
initial = [(0,0), (0,1), (0,2)]
game = GameOfLife(initial)
ani = animation.FuncAnimation(fig, game.plot_step)
plt.show()
如果你真的想避免上课,你也可以像这样重写程序:
def step(state):
newstate = state[:] # TODO Game of Life implementation goes here
return newstate
def plot(state):
# TODO: Plot here
def play_game(state):
while True:
yield state
state = step(state)
initial = [(0,0), (0,1), (0,2)]
game = play_game(initial)
ani = animation.FuncAnimation(fig, lambda: next(game))
plt.show()
答案 1 :(得分:1)
以下是使用没有自定义类的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
之间保存。
顺便说一下,警告“从不使用全局”并不够精确。我们一直使用全局变量。每次在模块级别导入模块时,模块对象都是全局的。每次在模块级别定义函数或类时,它都是全局的。使用全局变量没有任何问题(尽管从函数内部访问全局变量比访问函数的本地变速器更慢。但是,要注意预优化)。
或许这个告诫应该是“尝试永远不要使用改变状态的全局变量”。改变全局值的原因是因为改变全局的每个函数都变得无关紧要。该功能不再能够作为独立的代码单元来理解和测试。程序员用来解决问题的主要工具是将大问题分解成更小的问题。函数和类有助于将问题分解成更小的部分。但是当你使用变异全局变量时,你会失去这个好处。现在,头脑必须立即整理整个模块以理解代码。