Python 当只有一个成员被修改时,Pygame rect的所有成员变量是如何更新的?
运行此程序Python 当只有一个成员被修改时,Pygame rect的所有成员变量是如何更新的?,python,pygame,member,Python,Pygame,Member,运行此程序 import pygame pygame.init() r = pygame.Rect((0, 0), (100, 100)) r.center = (455, 455) print r 将作为输出。如果我要检查其他属性,如左上、中下或中心,它们也会被更新 这是非常有用的,但我不知道如何做到这一点。我直接更新成员,而不使用Rect类的任何成员函数。Python是否有某种“钩子”,可以在每次更新类的成员变量时执行?我可以用我自己的类来实现这一点,或者这是Pygame使用的特殊技
import pygame
pygame.init()
r = pygame.Rect((0, 0), (100, 100))
r.center = (455, 455)
print r
将
作为输出。如果我要检查其他属性,如左上
、中下
或中心
,它们也会被更新
这是非常有用的,但我不知道如何做到这一点。我直接更新成员,而不使用Rect类的任何成员函数。Python是否有某种“钩子”,可以在每次更新类的成员变量时执行?我可以用我自己的类来实现这一点,或者这是Pygame使用的特殊技巧?文档调用这些虚拟属性 在组成Rect类的C代码中,topleft如下所示:
/*topleft*/
static PyObject*
rect_gettopleft (PyRectObject *self, void *closure)
{
return Py_BuildValue ("(ii)", self->r.x, self->r.y);
}
static int
rect_settopleft (PyRectObject *self, PyObject* value, void *closure)
{
int val1, val2;
if (!TwoIntsFromObj (value, &val1, &val2))
{
RAISE (PyExc_TypeError, "invalid rect assignment");
return -1;
}
self->r.x = val1;
self->r.y = val2;
return 0;
}
…就像这样
/*topright*/
static PyObject*
rect_gettopright (PyRectObject *self, void *closure)
{
return Py_BuildValue ("(ii)", self->r.x+self->r.w, self->r.y);
}
static int
rect_settopright (PyRectObject *self, PyObject* value, void *closure)
{
int val1, val2;
if (!TwoIntsFromObj (value, &val1, &val2))
{
RAISE (PyExc_TypeError, "invalid rect assignment");
return -1;
}
self->r.x = val1-self->r.w;
self->r.y = val2;
return 0;
}
正如您在rect_gettopright
中所看到的,它是动态生成的;它添加self->r.x
和self->r.w
以返回右上角右侧“x”值的总值
基本上,是的,它们是方便挂钩
编辑:可以使用以下属性执行纯Python的版本:
class PyRect(object):
def __init__(self, x, y, w, h):
self.x = x
self.y = y
self.w = w
self.h = h
self._topright = None
@property
def topright(self):
if self._topright is None:
self._topright = (self.x + self.w, self.y)
return self._topright
@topright.setter
def topright(self, newx, newy):
self.x = newx - self.w
self.y = newy
self._topright = (newx, newy)
这真是又快又脏,但总体效果是一样的。回答得很好,而且通过C代码挖掘还可以获得额外的分数。