3

我一直在搞乱 pygame 和 python,我希望能够在我的类的属性发生变化时调用一个函数。我目前的解决方案是:

class ExampleClass(parentClass):
   def __init__(self):
      self.rect = pygame.rect.Rect(0,0,100,100)
   def __setattr__(self, name, value):
      parentClass.__setattr__(self,name,value)
      dofancystuff()
Firstclass = ExampleClass()

这很好用,当我用 更改 rect 值时会调用 dofancystuff Firsclass.rect = pygame.rect.Rect(0,0,100,100)。但是,如果我说Firstclass.rect.bottom = 3. __setattr__并没有调用 dofancystuff。

所以我想我的问题是如何拦截对子类属性的任何更改?

编辑:另外,如果我以错误的方式解决这个问题,请告诉我在 python 方面我不是很了解。

4

4 回答 4

4

嗯,简单的答案是你不能。在Firstclass.rect = <...>你的情况下__setattr__被称为。但是在调用 Rect 实例Firstclass.rect.bottom = 3__setattr__方法的情况下。我看到的唯一解决方案是创建一个派生类 pygame.rect.Rect 在其中覆盖该__setattr__方法。您也可以对 Rect 类进行猴子修补,但有充分的理由不鼓励这样做。

于 2009-03-24T10:46:29.483 回答
1

你可以试试__getattr__,应该叫上Firstclass.rect

但改为这样做:pygame.rectExampleClass.rect. __setattr__在那个类中实现。现在,您将被告知在您的rect成员中设置的任何内容ExampleClass。您仍然可以__setattr__ExampleClass(并且应该)中实现,只是现在确保您实例化您自己的rect类的版本......

顺便说一句:不要调用你的 objects Firstclass,因为它看起来像一个类而不是一个对象......

于 2009-03-24T10:39:20.390 回答
1

这没有回答问题,但它是相关的:

self.__dict__[name] = value

可能比

parentClass.__setattr__(self, name, value)

这是 Python 文档 (setattr">http://docs.python.org/2/reference/datamodel.html?highlight=setattr#object. setattr ) 推荐的,并且在一般情况下更有意义,因为它没有假设任何关于 parentClass setattr的行为。

是的,不请自来的建议已经晚了四年!

于 2013-04-07T16:56:26.487 回答
0

我认为您遇到这种困难的原因值得比其他答案提供的更多信息。

问题是,当你这样做时:

myObject.attribute.thing = value

您没有为属性分配值。代码等价于:

anAttribute = myObject.attribute
anAttribute.thing = value

正如 myObject 所见,您所做的一切都是为了获取属性;你没有设置属性。

制作您控制的属性的子类,并且可以为其定义 __setattr__ 是一种解决方案。

如果您有许多不同类型的属性并且不想为所有这些属性创建许多单独的子类,则另一种解决方案可能是有意义的,即覆盖 __getattribute__ 或 __getattr__ 以将外观返回到执行相关的属性__setattr__ 方法中的操作。我自己没有尝试过这样做,但我想您应该能够创建一个简单的外观类,它将充当任何对象的外观。

在选择__getattribute____getattr__时需要小心。有关信息,请参阅上一句中链接的文档,但基本上如果使用 __getattr__ ,实际属性将以某种方式封装/混淆,以便 __getattr__ 处理对它们的请求,如果使用 __getattribute__ ,则必须检索属性通过调用基类。

如果您要做的只是确定某些矩形是否已更新,那么这是矫枉过正的。

于 2009-07-11T01:07:07.823 回答