Вот пример использования 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()
При использовании выхода (в отличии от возврата) в функции, она делает функцию а generator. Функции генератора сохраняют состояние. Каждый раз, когда вы вызываете next
на итераторе, возвращенном генератором, поток выполнения берет вверх, где он остановился (из последнего выражения yield). Вот почему генераторы - это способ избежать глобальных привязок - потенциальные глобальные переменные являются лишь локальными переменными внутри функции генератора, и их состояние сохраняется между вызовами до next
.
Кстати, предупреждение «никогда не использовать глобалы» недостаточно точно. Мы постоянно используем глобальные переменные. Каждый раз, когда вы импортируете модуль на уровне модуля, объект модуля является глобальным. Каждый раз, когда вы определяете функцию или класс на уровне модуля, она является глобальной. Нет ничего плохого в использовании глобалов (хотя верно, что доступ к глобальным функциям изнутри функции медленнее, чем доступ к локальным функциям функции. Тем не менее, остерегайтесь предварительной оптимизации).
Возможно, вместо этого предупреждение должно гласить: «Не пытайтесь использовать глобальные переменные, которые меняют состояние». Причина, по которой изменение глобальных значений является плохим, состоит в том, что каждая функция, которая изменяет глобальную, становится бессвязной. Эта функция больше не может быть понята и протестирована как изолированная единица кода. Первичные инструменты-программисты используют для решения проблем, чтобы разбить большие проблемы на более мелкие части. Функции и классы помогают разбить проблемы на более мелкие куски. Но когда вы используете mutating globals, вы теряете это преимущество. Ум должен теперь заглянуть весь модуль сразу, чтобы понять код.
Я предполагал, что самым простым методом были функции imshow или pcolor с игрой данных типа жизни (сетка из двоичных целых чисел). В pygame, подумал я, мне придется рисовать доску самостоятельно. Я только недавно смотрел видео «прекратить использование классов», поэтому в последнее время я был непривлекательным для класса и был подсознательно решен без занятий. Является ли этот класс полезным, потому что это самый удобный способ получить результат из анимации (это в основном моя проблема, попытка обратной связи выходного состояния вернуться к шагу программы: вы можете дать ему вклад, но как вы получаете обновленное состояние?). –
В вашем примере, как называется метод шагов? Я ничего не вижу в [FuncAnimation documentation] (http://matplotlib.org/api/animation_api.html?highlight=funcanimation#matplotlib.animation.FuncAnimation). –
Пожалуйста, не следуйте советам, таким как «Прекратить использование классов», не понимая почему. Хотя вы, безусловно, могли бы использовать бесклассовый подход здесь, это, скорее всего, окажется более беспорядочным, чем это. 'FuncAnimation' ожидает произвольного вызываемого, и этот ответ проходит в функции' plot_step' объекта (здесь: единственного) 'GameOfLife', который сам называет' step'. – phihag