Python. Связь между экземплярами одного класса через обращение к атрибуту
Есть один класс. Есть два экземпляра этого класса.
Один движется (self.type = 'move'), второй не движется (self.type = 'stay').
Нужно, чтобы второй тоже двигался по координатам первого.
Может ли obj2 апеллируя атрибутом self.type обратиться к obj1, чтобы наследовать его координаты?
Вариант посредника в виде глобальной переменной известен, но нужно чтобы obj2 обращался непосредственно к obj1.
Помогите пожалуйста разобраться.
UPD: Важно, чтобы обращение происходило внутри класса, в методе Update, учитывая, что никакая информация вроде названий или индексов копий неизвестна, известен только атрибут self.type.
import pygame
pygame.init()
WIDTH, HEIGHT = WINDOW_SIZE = 800, 600
FPS = 60
window = pygame.display.set_mode(WINDOW_SIZE)
clock = pygame.time.Clock()
objects = []
class ObjectTest:
def __init__(self, type, x, y):
objects.append(self)
self.type = type
self.color = 'red'
self.rect = pygame.Rect(x, y, 64, 64)
def update(self):
if self.type == 'move':
self.rect.x += 1
self.color = 'green'
if self.type == 'stay':
# здесь нужно self.rect.x взять у копии с тайпом 'move'
self.color = 'white'
def draw(self):
pygame.draw.rect(window, self.color, self.rect)
obj1 = ObjectTest('move', 100, 100)
obj2 = ObjectTest('stay', 200, 200)
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
play = False
pygame.quit()
for i in objects: i.update()
window.fill('black')
for i in objects: i.draw()
pygame.display.update()
clock.tick(FPS)
Ответы (2 шт):
Я видимо не совсем понимаю, что вы хотите сделать.
Может вам просто добавить эту строку:
self.rect.x += 1в методеupdate()Или добавьте строку:
objects[1].rect.x = objects[0].rect.x
import sys
import pygame
pygame.init()
WIDTH, HEIGHT = WINDOW_SIZE = 800, 600
FPS = 60
window = pygame.display.set_mode(WINDOW_SIZE)
clock = pygame.time.Clock()
objects = []
class ObjectTest:
def __init__(self, type, x, y):
objects.append(self)
self.type = type
self.color = 'red'
self.rect = pygame.Rect(x, y, 64, 64)
def update(self):
if self.type == 'move':
self.rect.x += 1
self.color = 'green'
if self.type == 'stay':
self.color = 'white'
# ? self.rect.x += 1 # может вам просто добавить эту строку ?
def draw(self):
pygame.draw.rect(window, self.color, self.rect)
obj1 = ObjectTest('move', 100, 100)
obj2 = ObjectTest('stay', 200, 200)
obj3 = ObjectTest('123', 300, 300)
play = True
while play:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
play = False
# pygame.quit()
sys.exit()
for i in objects:
i.update()
window.fill('black')
for i in objects:
i.draw()
objects[1].rect.x = objects[0].rect.x # или попробуйте так
pygame.display.update()
clock.tick(FPS)
Кроме переменных экземпляра класса (то есть self) есть ещё переменные самого класса ObjectTest. Вы можете поместить список objects в переменные класса ObjectTest и при этом обращаться к нему через self, то есть через экземпляр класса (экземпляры имеют доступ к переменным класса):
class ObjectTest:
# список объектов теперь принадлежит всем объектам класса
objects = []
def __init__(self, type, x, y):
# добавляем новый экземпляр класса в список объектов класса
self.objects.append(self)
...
def update(self):
if self.type == 'move':
self.rect.x += 1
self.color = 'green'
if self.type == 'stay':
# перебираем объекты класса, ищем движущийся объект
for obj in self.objects:
# если нашли, то копируем его координату
if obj.type == 'move':
self.rect.x = obj.rect.x
self.color = 'white'
Внешне это выглядит похоже на использование глобальной переменной, но является более правильным подходом - список objects лежит не в глобальном пространстве, где непонятно, к чему он вообще относится, а лежит в классе, объекты которого он содержит.
Можно пойти дальше и, если у вас только по одному объекту каждого type, то завести словарь, а не список, у которого ключом будет type объекта. Тогда вам даже не нужно будет перебирать объекты, чтобы найти нужный:
class ObjectTest:
# словарь объектов
objects = {}
def __init__(self, type, x, y):
# добавляем новый экземпляр класса в словарь объектов класса
self.objects[type] = self
...
def update(self):
if self.type == 'move':
self.rect.x += 1
self.color = 'green'
if self.type == 'stay':
# ищем движущийся объект (он может быть ещё не добавлен)
obj = self.objects.get('move')
if obj in not None:
# если нашли, то копируем его координату
self.rect.x = obj.rect.x
self.color = 'white'
И type - плохое название для параметра функции, оно перекрывает встроенную функцию. Используйте type_. Вот в переменных класса можно оставить self.type как есть, насколько я помню.
