Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当只有一个成员被修改时,Pygame rect的所有成员变量是如何更新的?_Python_Pygame_Member - Fatal编程技术网

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代码挖掘还可以获得额外的分数。