Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/306.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 始终指向其他属性';s函数_Python_Class_Pygame - Fatal编程技术网

Python 始终指向其他属性';s函数

Python 始终指向其他属性';s函数,python,class,pygame,Python,Class,Pygame,我正在改进pythonic编码,想知道是否有一种方法可以始终指向同一类中的属性函数(包括“更新”其值) 简化的代码如下所示: class xyz: def __init__(self, widht, height): self.image = pygame.Surface((width, height)) self.rect = self.image.get_rect() obj = xyz(42, 42) obj.image = pygame.Surfa

我正在改进pythonic编码,想知道是否有一种方法可以始终指向同一类中的属性函数(包括“更新”其值)

简化的代码如下所示:

class xyz:
    def __init__(self, widht, height):
        self.image = pygame.Surface((width, height))
        self.rect = self.image.get_rect()
obj = xyz(42, 42)
obj.image = pygame.Surface((some_other_width, some_other_height))
# obj.rect would still be of size 42x42 and not the new values
import pygame

class xyz(pygame.sprite.Sprite):
    def __init__(self, width, height):
        super().__init__()
        self._image = pygame.Surface((width, height))
        self.rect = self.image.get_rect()

    @property
    def image(self):
        return self._image

    @image.setter
    def image(self, value):
        self._image = value
        self.rect = self._image.get_rect(topleft=self.rect.topleft)

obj = xyz(42, 42)
obj.rect.topleft = (300, 300)

print(obj.rect.width)   # prints 42
print(obj.rect.x)       # prints 300

obj.image = pygame.Surface((100, 100))

print(obj.rect.width)   # prints 100
print(obj.rect.x)       # prints 300
由于图像的大小是变化的,变化非常频繁,而且我的类必须有一个名为rect的属性,与当前图像的大小相同。是否有一个神奇的方法可以帮助update_rect()函数工作(尝试了一下self_ugetAttribute()uuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,但没有工作)


正如jonrsharpe在评论中所建议的,您可以使用属性。但是将
image
作为属性,而不是
rect
,如下所示:

class xyz:
    def __init__(self, widht, height):
        self.image = pygame.Surface((width, height))
        self.rect = self.image.get_rect()
obj = xyz(42, 42)
obj.image = pygame.Surface((some_other_width, some_other_height))
# obj.rect would still be of size 42x42 and not the new values
import pygame

class xyz(pygame.sprite.Sprite):
    def __init__(self, width, height):
        super().__init__()
        self._image = pygame.Surface((width, height))
        self.rect = self.image.get_rect()

    @property
    def image(self):
        return self._image

    @image.setter
    def image(self, value):
        self._image = value
        self.rect = self._image.get_rect(topleft=self.rect.topleft)

obj = xyz(42, 42)
obj.rect.topleft = (300, 300)

print(obj.rect.width)   # prints 42
print(obj.rect.x)       # prints 300

obj.image = pygame.Surface((100, 100))

print(obj.rect.width)   # prints 100
print(obj.rect.x)       # prints 300

这样,您还可以保留通常存储在
rect
属性中的位置。

rect
设置为只读,始终返回
self.image.get_rect()
。完美,感谢它与受保护的映像一起工作,只是想知道为什么具有公共属性的setter会抛出递归错误。。。我不再阅读oop im python了,它比我想象的更复杂:)@Robin你在答案中发布的代码导致溢出,因为在你调用的
image
setter中,给
self.image=image
,分配一些东西给
self.image
会再次调用setter,因此,再次调用
self.image=image
,依此类推。诀窍是将某个东西分配给某个属性不再真正分配某个东西;进行方法调用。因此,如果您将
self.image=image
看作
self.image(image)
,您将看到这是一个无限递归循环。如果我将所有属性都更改为protected,并像java中常见的那样使用getter和setter访问/更改它们,会更好吗?或者在这种情况下只是为了避免溢出吗?@Robin在Java中,如果在
setFoo(…)
内部调用
setFoo(…)
,您也会遇到同样的问题。我认为在Python中应该尽量少用属性。是的,我从来没有想过这一点,因为Java中的属性大多数时候都是私有的。。。从来没有在那个问题上绊倒过。。。。好吧,那很好,如果必要的话,我会用它们的。