【问题标题】:Intercepting changes of attributes in classes within a class - Python拦截类中类中属性的变化 - Python
【发布时间】:2010-10-15 04:17:00
【问题描述】:

我一直在搞乱 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()

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

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

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

【问题讨论】:

  • 您真正想要的可能是一个观察点,但 AFAIK pdb 尚不支持此功能。

标签: python class attributes subclass pygame


【解决方案1】:

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

【讨论】:

  • +1:创建您自己的矩形子类并将其用于所有内容。
【解决方案2】:

你可以试试__getattr__,它应该在Firstclass.rect上调用。

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

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

【讨论】:

    【解决方案3】:

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

    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 的行为。

    四年后主动提供建议太晚了!

    【讨论】:

      【解决方案4】:

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

      问题是,当你这样做时:

      myObject.attribute.thing = value
      

      您没有为属性分配值。代码相当于这样:

      anAttribute = myObject.attribute
      anAttribute.thing = value
      

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-09
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-03
        相关资源
        最近更新 更多