Я пытаюсь создать свою собственную версию прямоугольника pygame.Rect, но с добавленной функцией, заключающейся в том, что, когда квадрат выходит за пределы определенных мировых границ, он появляется на другой стороне.
Это означает, что мне пришлось переписать множество функций pygame.Rect в моем расширении, и мне это удалось. Здесь нет проблем.
Проблемы начинаются, когда я пытаюсь изменить __getattr__ и __setattr__. pygame.Rect интенсивно использует эти функции, так что, например, запрос «верх» или «низ» относится к «y» и «y» + «ширина» соответственно. Я изменил эти функции, чтобы они соответствовали моей функции, но мне нужно сделать еще одну вещь: в функции __init__ мне нужно создать переменные worldwidth и worldheight. Но я не могу, так как функция __setattr__ этого не позволяет.
Вот что у меня есть прямо сейчас:
class Rectinworld(pygame.Rect):
'''hides the fact that the world is round, when it comes to collisions and such'''
__slots__ = ['_r']
def __init__(self,(worldwidth,worldheight),*args):
object.__setattr__(self, "worldwidth",worldwidth)
if len(args)==0:
super(Rectinworld, self).__init__((0,0,0,0))
else:
super(Rectinworld, self).__init__(*args)
def __getattr__(self, name):
if name == 'top':
return self._r.y
#etc etc etc
elif name == 'height':
return self._r.h
else:
raise AttributeError(name)
def __setattr__(self, name, value):
if name == 'top' or name == 'y':
self._r.y = value % worldheight
#etc etc etc
elif name == 'height':
if int(value) < 0:
self._ensure_proxy()
self._r.h = int(value)
else:
raise AttributeError(name)
Я оставил код в #etc etc etc
комментариях для ясности. Код для pygame.Rect аналогичен: __setattr__ и __getattr__ не ссылаются на мировую ширину или мировую высоту, но в остальном они одинаковы, функция pygame.Rect .__ init__ очень длинная, но я думаю, что следующий фрагмент охватывает наиболее важные:
def __init__(self, *args):
#etc etc etc
if len(args) == 4:
if args[2] < 0 or args[3] < 0:
object.__setattr__(self, '_r', _RectProxy((int(args[0]),
int(args[1]),
int(args[2]),
int(args[3]))))
Полный код можно найти на странице https://github.com/brython-dev/brython-pygame/blob/master/pygame/rect.py.
Ошибка, которую я получаю сейчас:
line 10, in __init__
object.__setattr__(self, "worldwidth",0)
AttributeError: 'Rectinworld' object has no attribute 'worldwidth'
Кажется, очевидным исправлением является добавление ширины мира и высоты мира к __slots__ и дальнейшее продвижение оттуда. Это давало еще более странные ошибки. При попытке установить любую переменную будет выдано следующее сообщение:
line 65, in __getattr__
raise AttributeError(name)
AttributeError: _r
Короче говоря, мой вопрос сводится к следующему: почему я не могу создавать новые переменные и что мне нужно сделать, чтобы я мог?
__setattr__
? Разве вы не можете использоватьself._worldwidth
? - person furas   schedule 27.11.2017self._worldwidth
, но это не будет распознано функцией _ setattr_ и выдаст AttributeError - person user2424345   schedule 27.11.2017self._r = Rect()
внутриclass Rectinworld(object):
и использовал бы@property
- person furas   schedule 27.11.2017