Это, безусловно, вопрос новичка, мне просто трудно найти его.Как инициализировать данные для функции, которая неоднократно называется
Что я хочу сделать, так это рассчитать точки на круге для тысяч кругов, которые я позже вынести. Потому что я буду проводить много тысяч кругов в секунду, я думал, что постараюсь избежать лишних накладных расходов. Для этого я создал функцию, которая вычисляет количество точек (которые я хочу быть переменными, больший круг будет нуждаться в большем количестве вычислений) на единичном круге, а другая функция, которая может принимать эти точки, переводить их и затем масштабируйте радиус.
Мой исходный код в конечном итоге что-то вроде этого:
class Circle():
...
def CalcCircle(segments):
does some stuff to calculate generic coordinates
def CreateCircle(x, y, r, segments):
does some stuff to create a circle using CalcCircle(segments)
Очевидно, что проблема заключалась в том, что даже если я мог бы только создавать круги с 20 сегментами, я звоню функцию CalcCircle (и повторяя одни и те же расчеты) каждый раз, когда я вызывал CreateCircle.
Единственный способ, которым я мог понять, как исправить это:
class Circle():
...
def CalcCircle(segments):
does some stuff to calculate generic coordinates
CreateCircle_has_not_been_run = True
def CreateCircle(x, y, r, segments):
if Circle.TransCircle_has_not_been_run:
generic_circle = Circle.CalcCircle(segments)
Circle.CreateCircle_has_not_been_run = False
does some stuff to create a circle using generic_circle
Я никогда официально узнал программирования, так что я не уверен, если это считается хорошим дизайном. Конечно, это будет беспорядочно, если каждый раз, когда я хотел «инициализировать» данные или вызывать функцию только при первом прогоне, мне пришлось создать случайную переменную класса. Причина, по которой я спрашиваю, я постоянно сталкиваюсь с этой проблемой, поэтому я предполагаю, что должен быть стандартный способ сделать это.
Редактировать: пример того, как будет выполнен вызов.
@window.event
def on_draw():
window.clear()
width = window.get_size()[0]
height = window.get_size()[1]
radius = int(width/50)
segments = int(radius*1.5)
for i in range(N):
pyglet.gl.glColor3f(0.05,0.2,0.9)
DrawCircle(positions[i][0],positions[i][1],width,segments)
DrawCage(width,height)
DrawLabel(width,height)
etc.
Я знаю, что есть проблемы здесь, но я просто пытаюсь показать пример (позиция происходит от функции обновления, если кто-то интересно). Как я уже говорил ранее, это проблема, с которой я сталкиваюсь все время.
Я мог бы назвать Circle.CalcCircle() функцией on_resize() согласно предложению Ахима. Мне трудно поверить, однако, что стандартная практика состоит в том, чтобы вставить в класс две случайные функции (поскольку ни одна из них не обязана даже быть в классе Circle), одна из которых неявно зависит от другой, и обе из них вызывается в разных частях кода.
Почему вы не называете 'CalcCircle', сохраняете результат и передаете его в' CreateCircle'? – Achim
В этом случае, поскольку CreateCircle вызывается из функции on_draw, которая выполняет рендеринг каждые 16 миллисекунд или что-то еще. Кстати, у меня была точно такая же проблема с передачей 1000 ключевых слов в on_draw. Я хочу только изменить значения (и я не уверен, как это работает с памятью, если я повторно инициализирую 1000-клавишный словарь каждые 16 мс), в конце я использовал глобальный, который именно то, что я пытаюсь избежать , – user3573328
В целом, однако, стандартная практика состоит в том, чтобы иметь одну функцию для инициализации данных, а другую - для ее изменения? Я пытаюсь освободиться от менталитета глобального состояния и просто его модифицировать. Это несколько раздражает меня наличием функций, которые изменяют данные дальше по иерархии, если это имеет смысл. Или я не понимаю, что представляет собой хороший дизайн? – user3573328